Version Description
Download this release
Release Info
Developer | willmot |
Plugin | BackUpWordPress |
Version | 2.0 |
Comparing to | |
See all releases |
Code changes from version 1.6.9 to 2.0
- admin.actions.php +0 -297
- admin.backup-button.php +0 -9
- admin.backups-table.php +0 -40
- admin.page.php +0 -31
- admin.settings.php +0 -98
- admin.status.php +0 -55
- admin/actions.php +400 -0
- admin/backups.php +74 -0
- admin.constants.php → admin/constants.php +1 -16
- admin.menus.php → admin/menu.php +10 -10
- admin/page.php +19 -0
- admin/schedule-form-excludes.php +123 -0
- admin/schedule-form.php +60 -0
- admin/schedule.php +100 -0
- assets/fancyBox/CHANGELOG.md +55 -0
- assets/fancyBox/README.md +199 -0
- assets/fancyBox/demo/1_b.jpg +0 -0
- assets/fancyBox/demo/1_s.jpg +0 -0
- assets/fancyBox/demo/2_b.jpg +0 -0
- assets/fancyBox/demo/2_s.jpg +0 -0
- assets/fancyBox/demo/3_b.jpg +0 -0
- assets/fancyBox/demo/3_s.jpg +0 -0
- assets/fancyBox/demo/4_b.jpg +0 -0
- assets/fancyBox/demo/4_s.jpg +0 -0
- assets/fancyBox/demo/5_b.jpg +0 -0
- assets/fancyBox/demo/5_s.jpg +0 -0
- assets/fancyBox/demo/ajax.txt +15 -0
- assets/fancyBox/demo/iframe.html +22 -0
- assets/fancyBox/demo/index.html +302 -0
- assets/fancyBox/lib/jquery-1.7.2.min.js +4 -0
- assets/fancyBox/lib/jquery.mousewheel-3.0.6.pack.js +13 -0
- assets/fancyBox/source/blank.gif +0 -0
- assets/fancyBox/source/fancybox_loading.gif +0 -0
- assets/fancyBox/source/fancybox_sprite.png +0 -0
- assets/fancyBox/source/helpers/fancybox_buttons.png +0 -0
- assets/fancyBox/source/helpers/jquery.fancybox-buttons.css +85 -0
- assets/fancyBox/source/helpers/jquery.fancybox-buttons.js +115 -0
- assets/fancyBox/source/helpers/jquery.fancybox-media.js +86 -0
- assets/fancyBox/source/helpers/jquery.fancybox-thumbs.css +54 -0
- assets/fancyBox/source/helpers/jquery.fancybox-thumbs.js +157 -0
- assets/fancyBox/source/jquery.fancybox.css +226 -0
- assets/fancyBox/source/jquery.fancybox.js +1449 -0
- assets/fancyBox/source/jquery.fancybox.pack.js +35 -0
- assets/hmbkp.css +66 -8
- assets/hmbkp.js +306 -39
- assets/wpspin_light.gif +0 -0
- backupwordpress.mo +0 -0
- backupwordpress.po +338 -291
- classes/email.php +164 -0
- classes/schedule.php +779 -0
- classes/schedules.php +56 -0
- classes/services.php +233 -0
- classes/wp-cli.php +95 -0
- functions/backup.actions.php +0 -61
- functions/backup.functions.php +0 -294
- functions/core.functions.php +0 -558
- functions/core.php +362 -0
- functions/interface.functions.php +0 -202
- functions/interface.php +284 -0
- functions/wp-cli.php +0 -105
- hm-backup/hm-backup.php +701 -372
- languages/hmbkp-de_DE.mo +0 -0
- languages/hmbkp-de_DE.po +578 -363
- plugin.php +53 -51
- readme.txt +29 -13
- screenshot-1.png +0 -0
admin.actions.php
DELETED
@@ -1,297 +0,0 @@
|
|
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;
|
23 |
-
|
24 |
-
// Disable Automatic backups
|
25 |
-
if ( isset( $_POST['hmbkp_automatic'] ) && ! (bool) $_POST['hmbkp_automatic'] ) {
|
26 |
-
update_option( 'hmbkp_disable_automatic_backup', 'true' );
|
27 |
-
wp_clear_scheduled_hook( 'hmbkp_schedule_backup_hook' );
|
28 |
-
|
29 |
-
} else {
|
30 |
-
delete_option( 'hmbkp_disable_automatic_backup');
|
31 |
-
|
32 |
-
}
|
33 |
-
|
34 |
-
// Update schedule frequency settings. Or reset to default of daily.
|
35 |
-
if ( isset( $_POST['hmbkp_frequency'] ) && $_POST['hmbkp_frequency'] != 'daily' )
|
36 |
-
update_option( 'hmbkp_schedule_frequency', esc_attr( $_POST['hmbkp_frequency'] ) );
|
37 |
-
|
38 |
-
else
|
39 |
-
delete_option( 'hmbkp_schedule_frequency' );
|
40 |
-
|
41 |
-
// Clear schedule if settings have changed.
|
42 |
-
if ( wp_get_schedule( 'hmbkp_schedule_backup_hook' ) != get_option( 'hmbkp_schedule_frequency' ) )
|
43 |
-
wp_clear_scheduled_hook( 'hmbkp_schedule_backup_hook' );
|
44 |
-
|
45 |
-
if ( isset( $_POST['hmbkp_what_to_backup'] ) && $_POST['hmbkp_what_to_backup'] == 'files_only' ) {
|
46 |
-
|
47 |
-
update_option( 'hmbkp_files_only', 'true' );
|
48 |
-
delete_option( 'hmbkp_database_only' );
|
49 |
-
|
50 |
-
} elseif ( isset( $_POST['hmbkp_what_to_backup'] ) && $_POST['hmbkp_what_to_backup'] == 'database_only' ) {
|
51 |
-
|
52 |
-
update_option( 'hmbkp_database_only', 'true' );
|
53 |
-
delete_option( 'hmbkp_files_only' );
|
54 |
-
|
55 |
-
} else {
|
56 |
-
|
57 |
-
delete_option( 'hmbkp_database_only' );
|
58 |
-
delete_option( 'hmbkp_files_only' );
|
59 |
-
|
60 |
-
}
|
61 |
-
|
62 |
-
if ( isset( $_POST['hmbkp_backup_number'] ) && $max_backups = intval( $_POST['hmbkp_backup_number'] ) ) {
|
63 |
-
update_option( 'hmbkp_max_backups', intval( esc_attr( $_POST['hmbkp_backup_number'] ) ) );
|
64 |
-
|
65 |
-
} else {
|
66 |
-
delete_option( 'hmbkp_max_backups' );
|
67 |
-
|
68 |
-
// Only error if it is actually empty.
|
69 |
-
if ( isset( $_POST['hmbkp_backup_number'] ) )
|
70 |
-
$hmbkp_errors->add( 'invalid_no_backups', __( 'You have entered an invalid number of backups.', 'hmbkp' ) );
|
71 |
-
|
72 |
-
}
|
73 |
-
|
74 |
-
|
75 |
-
if ( isset( $_POST['hmbkp_email_address'] ) ) {
|
76 |
-
|
77 |
-
foreach( array_filter( array_map( 'trim', explode( ',', $_POST['hmbkp_email_address'] ) ) ) as $email_address )
|
78 |
-
if ( ! is_email( $email_address ) && $email_error = true )
|
79 |
-
$hmbkp_errors->add( 'invalid_email', sprintf( __( '%s is an invalid email address.', 'hmbkp' ), $email_address ) );
|
80 |
-
|
81 |
-
if ( empty( $email_error ) )
|
82 |
-
update_option( 'hmbkp_email_address', $_POST['hmbkp_email_address'] );
|
83 |
-
|
84 |
-
if ( isset( $_POST['hmbkp_email_address'] ) && empty( $_POST['hmbkp_email_address'] ) )
|
85 |
-
delete_option( 'hmbkp_email_address' );
|
86 |
-
|
87 |
-
}
|
88 |
-
|
89 |
-
if ( isset( $_POST['hmbkp_excludes'] ) && ! empty( $_POST['hmbkp_excludes'] ) ) {
|
90 |
-
update_option( 'hmbkp_excludes', $_POST['hmbkp_excludes'] );
|
91 |
-
|
92 |
-
} else {
|
93 |
-
delete_option( 'hmbkp_excludes' );
|
94 |
-
|
95 |
-
}
|
96 |
-
|
97 |
-
delete_transient( 'hmbkp_estimated_filesize' );
|
98 |
-
|
99 |
-
if ( $hmbkp_errors->get_error_code() )
|
100 |
-
return $hmbkp_errors;
|
101 |
-
|
102 |
-
return true;
|
103 |
-
|
104 |
-
}
|
105 |
-
add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_option_save' );
|
106 |
-
|
107 |
-
/**
|
108 |
-
* Delete the backup and then redirect
|
109 |
-
* back to the backups page
|
110 |
-
*/
|
111 |
-
function hmbkp_request_delete_backup() {
|
112 |
-
|
113 |
-
if ( ! isset( $_GET['hmbkp_delete'] ) || empty( $_GET['hmbkp_delete'] ) )
|
114 |
-
return;
|
115 |
-
|
116 |
-
hmbkp_delete_backup( $_GET['hmbkp_delete'] );
|
117 |
-
|
118 |
-
wp_redirect( remove_query_arg( 'hmbkp_delete' ), 303 );
|
119 |
-
|
120 |
-
exit;
|
121 |
-
|
122 |
-
}
|
123 |
-
add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_delete_backup' );
|
124 |
-
|
125 |
-
/**
|
126 |
-
* Perform a manual backup and then
|
127 |
-
* redirect back to the backups page
|
128 |
-
*/
|
129 |
-
function hmbkp_request_do_backup() {
|
130 |
-
|
131 |
-
if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_backup_now' )
|
132 |
-
return;
|
133 |
-
|
134 |
-
hmbkp_do_backup();
|
135 |
-
|
136 |
-
wp_redirect( remove_query_arg( 'action' ), 303 );
|
137 |
-
|
138 |
-
exit;
|
139 |
-
|
140 |
-
}
|
141 |
-
add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_do_backup' );
|
142 |
-
|
143 |
-
/**
|
144 |
-
* Perform a manual backup via ajax
|
145 |
-
*/
|
146 |
-
function hmbkp_ajax_request_do_backup() {
|
147 |
-
|
148 |
-
ignore_user_abort( true );
|
149 |
-
|
150 |
-
hmbkp_do_backup();
|
151 |
-
|
152 |
-
exit;
|
153 |
-
|
154 |
-
}
|
155 |
-
add_action( 'wp_ajax_hmbkp_backup', 'hmbkp_ajax_request_do_backup' );
|
156 |
-
|
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 ( empty( $_GET['hmbkp_download'] ) )
|
164 |
-
return;
|
165 |
-
|
166 |
-
// Force the .htaccess to be rebuilt
|
167 |
-
if ( file_exists( hmbkp_path() . '/.htaccess' ) )
|
168 |
-
unlink( hmbkp_path() . '/.htaccess' );
|
169 |
-
|
170 |
-
// Force a refresh of the HMBKP_SECURE_KEY in .htaccess
|
171 |
-
hmbkp_path();
|
172 |
-
|
173 |
-
wp_redirect( add_query_arg( 'key', md5( HMBKP_SECURE_KEY ), str_replace( realpath( hmbkp_conform_dir( get_home_path() ) ), home_url(), base64_decode( $_GET['hmbkp_download'] ) ) ), 303 );
|
174 |
-
|
175 |
-
exit;
|
176 |
-
|
177 |
-
}
|
178 |
-
add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_download_backup' );
|
179 |
-
|
180 |
-
function hmbkp_request_cancel_backup() {
|
181 |
-
|
182 |
-
if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_cancel' )
|
183 |
-
return;
|
184 |
-
|
185 |
-
hmbkp_cleanup();
|
186 |
-
|
187 |
-
wp_redirect( remove_query_arg( 'action' ), 303 );
|
188 |
-
|
189 |
-
exit;
|
190 |
-
|
191 |
-
}
|
192 |
-
add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_cancel_backup' );
|
193 |
-
|
194 |
-
function hmbkp_dismiss_error() {
|
195 |
-
|
196 |
-
if ( empty( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_dismiss_error' )
|
197 |
-
return;
|
198 |
-
|
199 |
-
hmbkp_cleanup();
|
200 |
-
|
201 |
-
wp_redirect( remove_query_arg( 'action' ), 303 );
|
202 |
-
|
203 |
-
exit;
|
204 |
-
|
205 |
-
}
|
206 |
-
add_action( 'admin_init', 'hmbkp_dismiss_error' );
|
207 |
-
|
208 |
-
/**
|
209 |
-
* Display the running status via ajax
|
210 |
-
*
|
211 |
-
* @return void
|
212 |
-
*/
|
213 |
-
function hmbkp_ajax_is_backup_in_progress() {
|
214 |
-
|
215 |
-
if ( ! hmbkp_in_progress() )
|
216 |
-
echo 0;
|
217 |
-
|
218 |
-
else
|
219 |
-
include( HMBKP_PLUGIN_PATH . '/admin.backup-button.php' );
|
220 |
-
|
221 |
-
exit;
|
222 |
-
|
223 |
-
}
|
224 |
-
add_action( 'wp_ajax_hmbkp_is_in_progress', 'hmbkp_ajax_is_backup_in_progress' );
|
225 |
-
|
226 |
-
/**
|
227 |
-
* Display the calculated size via ajax
|
228 |
-
*
|
229 |
-
* @return void
|
230 |
-
*/
|
231 |
-
function hmbkp_ajax_calculate_backup_size() {
|
232 |
-
|
233 |
-
echo hmbkp_calculate();
|
234 |
-
|
235 |
-
exit;
|
236 |
-
|
237 |
-
}
|
238 |
-
add_action( 'wp_ajax_hmbkp_calculate', 'hmbkp_ajax_calculate_backup_size' );
|
239 |
-
|
240 |
-
/**
|
241 |
-
* Test the cron response and if it's not 200 show a warning message
|
242 |
-
*
|
243 |
-
* @return void
|
244 |
-
*/
|
245 |
-
function hmbkp_ajax_cron_test() {
|
246 |
-
|
247 |
-
$response = wp_remote_get( site_url( 'wp-cron.php' ) );
|
248 |
-
|
249 |
-
if ( ! is_wp_error( $response ) && $response['response']['code'] != '200' )
|
250 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( '%1$s is returning a %2$s response which could mean cron jobs aren\'t getting fired properly. BackUpWordPress relies on wp-cron to run scheduled back ups. See the %3$s for more details.', 'hmbkp' ), '<code>wp-cron.php</code>', '<code>' . $response['response']['code'] . '</code>', '<a href="http://wordpress.org/extend/plugins/backupwordpress/faq/">FAQ</a>' ) . '</p></div>';
|
251 |
-
|
252 |
-
else
|
253 |
-
echo 1;
|
254 |
-
|
255 |
-
exit;
|
256 |
-
|
257 |
-
}
|
258 |
-
add_action( 'wp_ajax_hmbkp_cron_test', 'hmbkp_ajax_cron_test' );
|
259 |
-
|
260 |
-
/**
|
261 |
-
* Handles changes in the defined Constants
|
262 |
-
* that users can define to control advanced
|
263 |
-
* settings
|
264 |
-
*
|
265 |
-
* @return null
|
266 |
-
*/
|
267 |
-
function hmbkp_constant_changes() {
|
268 |
-
|
269 |
-
// Check whether we need to disable the cron
|
270 |
-
if ( hmbkp_get_disable_automatic_backup() && wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) )
|
271 |
-
wp_clear_scheduled_hook( 'hmbkp_schedule_backup_hook' );
|
272 |
-
|
273 |
-
// Or whether we need to re-enable it
|
274 |
-
if ( ! hmbkp_get_disable_automatic_backup() && ! wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) )
|
275 |
-
hmbkp_setup_schedule();
|
276 |
-
|
277 |
-
// Allow the time of the daily backup to be changed
|
278 |
-
if ( wp_get_schedule( 'hmbkp_schedule_backup_hook' ) != get_option( 'hmbkp_schedule_frequency' ) )
|
279 |
-
hmbkp_setup_schedule();
|
280 |
-
|
281 |
-
// Reset if custom time is removed
|
282 |
-
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() )
|
283 |
-
hmbkp_setup_schedule();
|
284 |
-
|
285 |
-
// If a custom backup path has been set or changed
|
286 |
-
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH && hmbkp_conform_dir( HMBKP_PATH ) != ( $from = hmbkp_conform_dir( get_option( 'hmbkp_path' ) ) ) )
|
287 |
-
hmbkp_path_move( $from, HMBKP_PATH );
|
288 |
-
|
289 |
-
// If a custom backup path has been removed
|
290 |
-
if ( ( ( defined( 'HMBKP_PATH' ) && ! HMBKP_PATH ) || ! defined( 'HMBKP_PATH' ) && hmbkp_conform_dir( hmbkp_path_default() ) != ( $from = hmbkp_conform_dir( get_option( 'hmbkp_path' ) ) ) ) )
|
291 |
-
hmbkp_path_move( $from, hmbkp_path_default() );
|
292 |
-
|
293 |
-
// If the custom path has changed and the new directory isn't writable
|
294 |
-
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH && hmbkp_conform_dir( HMBKP_PATH ) != ( $from = hmbkp_conform_dir( get_option( 'hmbkp_path' ) ) ) && $from != hmbkp_path_default() && !is_writable( HMBKP_PATH ) && is_dir( $from ) )
|
295 |
-
hmbkp_path_move( $from, hmbkp_path_default() );
|
296 |
-
|
297 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin.backup-button.php
DELETED
@@ -1,9 +0,0 @@
|
|
1 |
-
<?php if ( hmbkp_in_progress() ) : ?>
|
2 |
-
|
3 |
-
<a id="hmbkp_backup" class="add-new-h2 hmbkp_running" href="tools.php?page=<?php echo HMBKP_PLUGIN_SLUG; ?>&action=hmbkp_cancel"><?php echo hmbkp_get_status(); ?> [<?php _e( 'cancel', 'hmbkp' ); ?>]</a>
|
4 |
-
|
5 |
-
<?php elseif ( hmbkp_possible() ) : ?>
|
6 |
-
|
7 |
-
<a id="hmbkp_backup" class="add-new-h2" href="tools.php?page=<?php echo HMBKP_PLUGIN_SLUG; ?>&action=hmbkp_backup_now"><?php _e( 'Back Up Now', 'hmbkp' ); ?></a>
|
8 |
-
|
9 |
-
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin.backups-table.php
DELETED
@@ -1,40 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
// If max backups has changed
|
4 |
-
if ( ! hmbkp_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>
|
11 |
-
<tr>
|
12 |
-
<th scope="col"><?php printf( _n( '1 backup completed', '%d backups completed', count( $backup_archives ), 'hmbkp' ), count( $backup_archives ) ); ?></th>
|
13 |
-
<th scope="col"><?php _e( 'Size', 'hmbkp' ); ?></th>
|
14 |
-
<th scope="col"><?php _e( 'Actions', 'hmbkp' ); ?></th>
|
15 |
-
</tr>
|
16 |
-
</thead>
|
17 |
-
|
18 |
-
<tfoot>
|
19 |
-
<tr>
|
20 |
-
<th><?php printf( _n( 'Only the most recent backup will be saved', 'The %d most recent backups will be saved', hmbkp_max_backups(), 'hmbkp' ), hmbkp_max_backups() ); ?></th>
|
21 |
-
<th><?php printf( __( 'Total %s', 'hmbkp' ), hmbkp_total_filesize() ); ?></th>
|
22 |
-
<th></th>
|
23 |
-
</tr>
|
24 |
-
</tfoot>
|
25 |
-
|
26 |
-
<tbody id="the-list">
|
27 |
-
|
28 |
-
<?php foreach ( (array) $backup_archives as $file ) :
|
29 |
-
|
30 |
-
if ( ! file_exists( $file ) )
|
31 |
-
continue;
|
32 |
-
|
33 |
-
hmbkp_get_backup_row( $file );
|
34 |
-
|
35 |
-
endforeach; ?>
|
36 |
-
|
37 |
-
</tbody>
|
38 |
-
</table>
|
39 |
-
|
40 |
-
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin.page.php
DELETED
@@ -1,31 +0,0 @@
|
|
1 |
-
<div class="wrap<?php if ( hmbkp_in_progress() ) { ?> hmbkp_running<?php } ?>">
|
2 |
-
|
3 |
-
<?php screen_icon( 'backupwordpress' ); ?>
|
4 |
-
|
5 |
-
<h2>
|
6 |
-
|
7 |
-
<?php _e( 'Manage Backups', 'hmbkp' ); ?>
|
8 |
-
|
9 |
-
<?php include_once( HMBKP_PLUGIN_PATH . '/admin.backup-button.php' ); ?>
|
10 |
-
|
11 |
-
<a class="add-new-h2 hmbkp-settings-toggle" href="#hmbkp-settings"><?php _e( 'Settings', 'hmbkp' ); ?></a>
|
12 |
-
|
13 |
-
</h2>
|
14 |
-
|
15 |
-
<?php if ( hmbkp_possible() ) : ?>
|
16 |
-
|
17 |
-
<?php include_once( HMBKP_PLUGIN_PATH . '/admin.status.php' ); ?>
|
18 |
-
|
19 |
-
<?php include_once( HMBKP_PLUGIN_PATH . '/admin.backups-table.php' ); ?>
|
20 |
-
|
21 |
-
<?php else : ?>
|
22 |
-
|
23 |
-
<p><strong><?php _e( 'You need to fix the issues detailed above before BackUpWordPress can start.', 'hmbkp' ); ?></strong></p>
|
24 |
-
|
25 |
-
<?php endif; ?>
|
26 |
-
|
27 |
-
<?php include_once( HMBKP_PLUGIN_PATH . '/admin.settings.php' ); ?>
|
28 |
-
|
29 |
-
<p class="howto"><?php printf( __( 'If you need help getting things working you are more than welcome to email us at %s and we\'ll do what we can to help.', 'hmbkp' ), '<a href="mailto:support@humanmade.co.uk">support@humanmade.co.uk</a>' ); ?></p>
|
30 |
-
|
31 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin.settings.php
DELETED
@@ -1,98 +0,0 @@
|
|
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 %1$s in your %2$s to control some settings. A full list of %3$s can be found in the %4$s. Defined settings will not be editable below.', 'hmbkp' ), '<code>' . __( 'Constants', 'hmbkp' ) . '</code>', '<code>wp-config.php</code>', '<code>' . __( 'Constants', 'hmbkp' ) . '</code>', '<a href="#contextual-help-wrap" class="hmbkp-show-help-tab">' . __( 'help panel', 'hmbkp' ) . '</a>' ); ?></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>
|
13 |
-
|
14 |
-
<tr align="top">
|
15 |
-
|
16 |
-
<th scope="row"><?php _e( 'Automatic Backups', 'hmbkp' ); ?></th>
|
17 |
-
|
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 |
-
|
25 |
-
<label for="hmbkp_automatic_off">
|
26 |
-
<input name="hmbkp_automatic" type="radio" id="hmbkp_automatic_off" value="0" <?php checked( hmbkp_get_disable_automatic_backup() ); ?> <?php disabled( defined( 'HMBKP_DISABLE_AUTOMATIC_BACKUP' ) ); ?>>
|
27 |
-
<?php _e( 'No automatic backups.', 'hmbkp' ); ?>
|
28 |
-
</label>
|
29 |
-
|
30 |
-
</td>
|
31 |
-
|
32 |
-
</tr>
|
33 |
-
|
34 |
-
<tr align="top">
|
35 |
-
|
36 |
-
<th scope="row"><label for="hmbkp_frequency"><?php _e( 'Frequency of backups', 'hmbkp' ); ?></label></th>
|
37 |
-
|
38 |
-
<td>
|
39 |
-
|
40 |
-
<?php _e( 'Automatic backups will occur', 'hmbkp' ); ?>
|
41 |
-
|
42 |
-
<select name="hmbkp_frequency" id="hmbkp_frequency">
|
43 |
-
<option value="daily" <?php selected( ! get_option( 'hmbkp_schedule_frequency' ) ); ?>><?php _e( 'Daily', 'hmbkp' ); ?></option>
|
44 |
-
<option value="hmbkp_weekly" <?php selected( get_option( 'hmbkp_schedule_frequency' ), 'hmbkp_weekly' ); ?>><?php _e( 'Weekly', 'hmbkp' ); ?></option>
|
45 |
-
<option value="hmbkp_fortnightly" <?php selected( get_option( 'hmbkp_schedule_frequency' ), 'hmbkp_fortnightly' ); ?>><?php _e( 'Fortnightly', 'hmbkp' ); ?></option>
|
46 |
-
<option value="hmbkp_monthly" <?php selected( get_option( 'hmbkp_schedule_frequency' ), 'hmbkp_monthly' ); ?>><?php _e( 'Monthly', 'hmbkp' ); ?></option>
|
47 |
-
</select>
|
48 |
-
|
49 |
-
</td>
|
50 |
-
|
51 |
-
</tr>
|
52 |
-
|
53 |
-
<tr align="top">
|
54 |
-
|
55 |
-
<th scope="row"><label for="hmbkp_what_to_backup"><?php _e( 'What to Backup', 'hmbkp' ); ?></label></th>
|
56 |
-
|
57 |
-
<td>
|
58 |
-
|
59 |
-
<?php _e( 'Backup my', 'hmbkp' ); ?>
|
60 |
-
|
61 |
-
<select name="hmbkp_what_to_backup" id="hmbkp_what_to_backup" <?php disabled( defined( 'HMBKP_FILES_ONLY' ) || defined( 'HMBKP_DATABASE_ONLY' ) ); ?>>
|
62 |
-
<option value="default" <?php selected( ! get_option( 'hmbkp_files_only' ) && !get_option( 'hmbkp_database_only' ) ); ?>><?php _e( 'database & files', 'hmbkp' ); ?></option>
|
63 |
-
<option value="database_only" <?php selected( hmbkp_get_database_only() ); ?>><?php _e( 'database only', 'hmbkp' ); ?></option>
|
64 |
-
<option value="files_only" <?php selected( hmbkp_get_files_only() ); ?>><?php _e( 'files only', 'hmbkp' ); ?></option>
|
65 |
-
</select>
|
66 |
-
|
67 |
-
</td>
|
68 |
-
|
69 |
-
</tr>
|
70 |
-
|
71 |
-
<tr align="top">
|
72 |
-
<th scope="row"><label for="hmbkp_backup_number"><?php _e( 'Number of backups', 'hmbkp' ); ?></label></th>
|
73 |
-
<td><label for="hmbkp_backup_number"><?php printf( __( 'The last %s backups will be stored on the server.', 'hmbkp' ), '<input type="text" class="small-text ' . ( defined( 'HMBKP_MAX_BACKUPS' ) ? 'disabled' : '' ) . '" value="' . hmbkp_max_backups() . '" id="hmbkp_backup_number" name="hmbkp_backup_number"' . disabled( defined( 'HMBKP_MAX_BACKUPS' ), true, false ) . '>' ); ?></label></td>
|
74 |
-
</tr>
|
75 |
-
|
76 |
-
<tr valign="top">
|
77 |
-
<th scope="row"><label for="hmbkp_email_address"><?php _e( 'Email backups', 'hmbkp' ); ?></label></th>
|
78 |
-
<td><input name="hmbkp_email_address" type="text" id="hmbkp_email_address" value="<?php echo ! empty( $_POST['hmbkp_email_address'] ) ? $_POST['hmbkp_email_address'] : hmbkp_get_email_address( 'list' ); ?>" class="regular-text <?php if ( defined( 'HMBKP_EMAIL' ) ) echo 'disabled'; ?>" <?php disabled( defined( 'HMBKP_EMAIL' ) ); ?>> <span class="description"><?php _e( 'A copy of the backup file will be emailed to this address. Disabled if left blank.', 'hmbkp' ); ?></span></td>
|
79 |
-
</tr>
|
80 |
-
|
81 |
-
<tr align="top">
|
82 |
-
<th scope="row"><label for="hmbkp_excludes"><?php _e( 'Excludes', 'hmbkp' ); ?></th>
|
83 |
-
<td>
|
84 |
-
<textarea class="code large-text<?php if ( defined( 'HMBKP_EXCLUDE' ) || hmbkp_get_database_only() ) echo ' disabled' ?>" name="hmbkp_excludes" id="hmbkp_excludes" <?php disabled( defined( 'HMBKP_EXCLUDE' ) || hmbkp_get_database_only() ); ?>><?php echo hmbkp_get_excludes(); ?></textarea>
|
85 |
-
<span class="description"><?php _e( 'A comma separated list of file and directory paths that you do <strong>not</strong> want to backup.', 'hmbkp' ); ?></span><br/>
|
86 |
-
<?php _e( 'e.g.', 'hmbkp' ); ?> <code>file.php, /directory/, /directory/file.jpg</code>
|
87 |
-
</td>
|
88 |
-
</tr>
|
89 |
-
|
90 |
-
</tbody>
|
91 |
-
|
92 |
-
</table>
|
93 |
-
|
94 |
-
<p class="submit"><input type="submit" name="hmbkp_settings_submit" id="submit" class="button-primary" value="<?php _e( 'Save Changes', 'hmbkp' ); ?>"></p>
|
95 |
-
|
96 |
-
</form>
|
97 |
-
|
98 |
-
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin.status.php
DELETED
@@ -1,55 +0,0 @@
|
|
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>✓
|
6 |
-
|
7 |
-
<?php if ( hmbkp_get_disable_automatic_backup() && !wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) ) : ?>
|
8 |
-
|
9 |
-
<?php printf( __( 'Automatic backups are %s.', 'hmbkp' ), '<strong>' . __( 'disabled', 'hmbkp' ) . '</strong>' ); ?>
|
10 |
-
|
11 |
-
<?php else :
|
12 |
-
|
13 |
-
if ( ! hmbkp_get_database_only() && ! hmbkp_get_files_only() ) :
|
14 |
-
$what_to_backup = '<code>' . __( 'database', 'hmbkp' ) . '</code> ' . __( '&', 'hmbkp' ) . ' <code>' . __( 'files', 'hmbkp' ) . '</code>';
|
15 |
-
$count = 2;
|
16 |
-
|
17 |
-
elseif ( hmbkp_get_database_only() ) :
|
18 |
-
$what_to_backup = '<code>' . __( 'database', 'hmbkp' ) . '</code>';
|
19 |
-
$count = 1;
|
20 |
-
|
21 |
-
else :
|
22 |
-
$what_to_backup = '<code>' . __( 'files', 'hmbkp' ) . '</code>';
|
23 |
-
$count = 2;
|
24 |
-
|
25 |
-
endif;
|
26 |
-
|
27 |
-
$offset = current_time( 'timestamp' ) - time();
|
28 |
-
$schedules = wp_get_schedules();
|
29 |
-
$schedule = $schedules[wp_get_schedule( 'hmbkp_schedule_backup_hook' )]['display'];
|
30 |
-
printf(
|
31 |
-
_n(
|
32 |
-
'Your %1$s will be automatically backed up %2$s. The next backup will occur at %3$s on %4$s and be saved to %5$s.', // singular
|
33 |
-
'Your %1$s will be automatically backed up %2$s. The next backup will occur at %3$s on %4$s and be saved to %5$s.', // plural
|
34 |
-
$count, 'hmbkp'
|
35 |
-
),
|
36 |
-
$what_to_backup,
|
37 |
-
'<code>' . $schedule . '</code>',
|
38 |
-
'<code>' . date_i18n( get_option( 'time_format' ), wp_next_scheduled( 'hmbkp_schedule_backup_hook' ) + $offset ) . '</code>',
|
39 |
-
'<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>',
|
40 |
-
'<code>' . hmbkp_path() . '</code>'
|
41 |
-
); ?>
|
42 |
-
|
43 |
-
<?php endif; ?>
|
44 |
-
|
45 |
-
</p>
|
46 |
-
|
47 |
-
<p>✓ <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>
|
48 |
-
|
49 |
-
<?php if ( hmbkp_get_email_address() ) : ?>
|
50 |
-
<p>✓ <?php printf( __( 'A copy of each backup will be emailed to %s.', 'hmbkp' ), '<code>' . implode( '</code>, <code>', array_filter( hmbkp_get_email_address(), 'is_email' ) ) . '</code>' ); ?></p>
|
51 |
-
<?php endif; ?>
|
52 |
-
|
53 |
-
<?php if ( ( $valid_excludes = hmbkp_valid_custom_excludes() ) && ! hmbkp_get_database_only() ) : ?>
|
54 |
-
<p>✓ <?php printf( __( 'The following paths will be excluded from your backups %s.', 'hmbkp' ), '<code>' . implode( '</code>, <code>', $valid_excludes ) . '</code>' ); ?></p>
|
55 |
-
<?php endif; ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
admin/actions.php
ADDED
@@ -0,0 +1,400 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Delete the backup and then redirect
|
5 |
+
* back to the backups page
|
6 |
+
*/
|
7 |
+
function hmbkp_request_delete_backup() {
|
8 |
+
|
9 |
+
if ( empty( $_GET['hmbkp_delete_backup'] ) || ! check_admin_referer( 'hmbkp-delete_backup' ) )
|
10 |
+
return;
|
11 |
+
|
12 |
+
$schedule = new HMBKP_Scheduled_Backup( urldecode( $_GET['hmbkp_schedule_id'] ) );
|
13 |
+
$schedule->delete_backup( base64_decode( urldecode( $_GET['hmbkp_delete_backup'] ) ) );
|
14 |
+
|
15 |
+
wp_redirect( remove_query_arg( array( 'hmbkp_delete_backup', '_wpnonce' ) ), 303 );
|
16 |
+
|
17 |
+
exit;
|
18 |
+
|
19 |
+
}
|
20 |
+
add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_delete_backup' );
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Delete a schedule and all it's backups and then redirect
|
24 |
+
* back to the backups page
|
25 |
+
*/
|
26 |
+
function hmbkp_request_delete_schedule() {
|
27 |
+
|
28 |
+
if ( empty( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_delete_schedule' || ! check_admin_referer( 'hmbkp-delete_schedule' ) )
|
29 |
+
return;
|
30 |
+
|
31 |
+
$schedule = new HMBKP_Scheduled_Backup( urldecode( $_GET['hmbkp_schedule_id'] ) );
|
32 |
+
$schedule->cancel( true );
|
33 |
+
|
34 |
+
wp_redirect( remove_query_arg( array( 'hmbkp_schedule_id', 'action', '_wpnonce' ) ), 303 );
|
35 |
+
|
36 |
+
exit;
|
37 |
+
|
38 |
+
}
|
39 |
+
add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_delete_schedule' );
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Perform a manual backup via ajax
|
43 |
+
*/
|
44 |
+
function hmbkp_ajax_request_do_backup() {
|
45 |
+
|
46 |
+
if ( empty( $_GET['hmbkp_schedule_id'] ) )
|
47 |
+
return;
|
48 |
+
|
49 |
+
ignore_user_abort( true );
|
50 |
+
|
51 |
+
hmbkp_cleanup();
|
52 |
+
|
53 |
+
$schedule = new HMBKP_Scheduled_Backup( urldecode( $_GET['hmbkp_schedule_id'] ) );
|
54 |
+
|
55 |
+
$schedule->run();
|
56 |
+
|
57 |
+
hmbkp_schedule_actions( $schedule );
|
58 |
+
|
59 |
+
exit;
|
60 |
+
|
61 |
+
}
|
62 |
+
add_action( 'wp_ajax_hmbkp_run_schedule', 'hmbkp_ajax_request_do_backup' );
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Send the download file to the browser and
|
66 |
+
* then redirect back to the backups page
|
67 |
+
*/
|
68 |
+
function hmbkp_request_download_backup() {
|
69 |
+
|
70 |
+
if ( empty( $_GET['hmbkp_download_backup'] ) || ! check_admin_referer( 'hmbkp-download_backup' ) )
|
71 |
+
return;
|
72 |
+
|
73 |
+
wp_redirect( str_replace( realpath( HM_Backup::conform_dir( HM_Backup::get_home_path() ) ), home_url(), base64_decode( $_GET['hmbkp_download_backup'] ) ), 303 );
|
74 |
+
|
75 |
+
exit;
|
76 |
+
|
77 |
+
}
|
78 |
+
add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_download_backup' );
|
79 |
+
|
80 |
+
/**
|
81 |
+
* cancels a running backup then redirect
|
82 |
+
* back to the backups page
|
83 |
+
*/
|
84 |
+
function hmbkp_request_cancel_backup() {
|
85 |
+
|
86 |
+
if ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_cancel' )
|
87 |
+
return;
|
88 |
+
|
89 |
+
$schedule = new HMBKP_Scheduled_Backup( urldecode( $_GET['hmbkp_schedule_id'] ) );
|
90 |
+
|
91 |
+
// Delete the running backup
|
92 |
+
if ( file_exists( trailingslashit( hmbkp_path() ) . $schedule->get_running_backup_filename() ) )
|
93 |
+
unlink( trailingslashit( hmbkp_path() ) . $schedule->get_running_backup_filename() );
|
94 |
+
|
95 |
+
hmbkp_cleanup();
|
96 |
+
|
97 |
+
wp_redirect( remove_query_arg( array( 'action' ) ), 303 );
|
98 |
+
|
99 |
+
exit;
|
100 |
+
|
101 |
+
}
|
102 |
+
add_action( 'load-tools_page_' . HMBKP_PLUGIN_SLUG, 'hmbkp_request_cancel_backup' );
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Dismiss an error and then redirect
|
106 |
+
* back to the backups page
|
107 |
+
*/
|
108 |
+
function hmbkp_dismiss_error() {
|
109 |
+
|
110 |
+
if ( empty( $_GET['action'] ) || $_GET['action'] !== 'hmbkp_dismiss_error' )
|
111 |
+
return;
|
112 |
+
|
113 |
+
hmbkp_cleanup();
|
114 |
+
|
115 |
+
wp_redirect( remove_query_arg( 'action' ), 303 );
|
116 |
+
|
117 |
+
exit;
|
118 |
+
|
119 |
+
}
|
120 |
+
add_action( 'admin_init', 'hmbkp_dismiss_error' );
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Display the running status via ajax
|
124 |
+
*/
|
125 |
+
function hmbkp_ajax_is_backup_in_progress() {
|
126 |
+
|
127 |
+
if ( empty( $_GET['hmbkp_schedule_id'] ) )
|
128 |
+
return;
|
129 |
+
|
130 |
+
$schedule = new HMBKP_Scheduled_Backup( urldecode( $_GET['hmbkp_schedule_id'] ) );
|
131 |
+
|
132 |
+
if ( ! $schedule->get_status() )
|
133 |
+
echo 0;
|
134 |
+
|
135 |
+
else
|
136 |
+
hmbkp_schedule_actions( $schedule );
|
137 |
+
|
138 |
+
exit;
|
139 |
+
|
140 |
+
}
|
141 |
+
add_action( 'wp_ajax_hmbkp_is_in_progress', 'hmbkp_ajax_is_backup_in_progress' );
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Display the calculated size via ajax
|
145 |
+
*/
|
146 |
+
function hmbkp_ajax_calculate_backup_size() {
|
147 |
+
|
148 |
+
if ( empty( $_GET['hmbkp_schedule_id'] ) )
|
149 |
+
return;
|
150 |
+
|
151 |
+
$schedule = new HMBKP_Scheduled_Backup( urldecode( $_GET['hmbkp_schedule_id'] ) );
|
152 |
+
|
153 |
+
$recalculate_filesize = true;
|
154 |
+
|
155 |
+
include_once( HMBKP_PLUGIN_PATH . '/admin/schedule.php' );
|
156 |
+
|
157 |
+
exit;
|
158 |
+
|
159 |
+
}
|
160 |
+
add_action( 'wp_ajax_hmbkp_calculate', 'hmbkp_ajax_calculate_backup_size' );
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Test the cron response and if it's not 200 show a warning message
|
164 |
+
*/
|
165 |
+
function hmbkp_ajax_cron_test() {
|
166 |
+
|
167 |
+
$response = wp_remote_get( site_url( 'wp-cron.php' ) );
|
168 |
+
|
169 |
+
if ( ! is_wp_error( $response ) && $response['response']['code'] != '200' )
|
170 |
+
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( '%1$s is returning a %2$s response which could mean cron jobs aren\'t getting fired properly. BackUpWordPress relies on wp-cron to run scheduled back ups. See the %3$s for more details.', 'hmbkp' ), '<code>wp-cron.php</code>', '<code>' . $response['response']['code'] . '</code>', '<a href="http://wordpress.org/extend/plugins/backupwordpress/faq/">FAQ</a>' ) . '</p></div>';
|
171 |
+
|
172 |
+
else
|
173 |
+
echo 1;
|
174 |
+
|
175 |
+
exit;
|
176 |
+
|
177 |
+
}
|
178 |
+
add_action( 'wp_ajax_hmbkp_cron_test', 'hmbkp_ajax_cron_test' );
|
179 |
+
|
180 |
+
/**
|
181 |
+
* Load the edit schedule form
|
182 |
+
*/
|
183 |
+
function hmbkp_edit_schedule_load() {
|
184 |
+
|
185 |
+
$schedule = new HMBKP_Scheduled_Backup( esc_attr( $_GET['hmbkp_schedule_id'] ) );
|
186 |
+
|
187 |
+
require( HMBKP_PLUGIN_PATH . '/admin/schedule-form.php' );
|
188 |
+
|
189 |
+
exit;
|
190 |
+
|
191 |
+
}
|
192 |
+
add_action( 'wp_ajax_hmbkp_edit_schedule_load', 'hmbkp_edit_schedule_load' );
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Load the edit schedule excludes form
|
196 |
+
*/
|
197 |
+
function hmbkp_edit_schedule_excludes_load() {
|
198 |
+
|
199 |
+
$schedule = new HMBKP_Scheduled_Backup( esc_attr( $_GET['hmbkp_schedule_id'] ) );
|
200 |
+
|
201 |
+
require( HMBKP_PLUGIN_PATH . '/admin/schedule-form-excludes.php' );
|
202 |
+
|
203 |
+
exit;
|
204 |
+
|
205 |
+
}
|
206 |
+
add_action( 'wp_ajax_hmbkp_edit_schedule_excludes_load', 'hmbkp_edit_schedule_excludes_load' );
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Load the add schedule form
|
210 |
+
*/
|
211 |
+
function hmbkp_add_schedule_load() {
|
212 |
+
|
213 |
+
$schedule = new HMBKP_Scheduled_Backup( date( 'U' ) );
|
214 |
+
$is_new_schedule = true;
|
215 |
+
|
216 |
+
require( HMBKP_PLUGIN_PATH . '/admin/schedule-form.php' );
|
217 |
+
|
218 |
+
exit;
|
219 |
+
|
220 |
+
}
|
221 |
+
add_action( 'wp_ajax_hmbkp_add_schedule_load', 'hmbkp_add_schedule_load' );
|
222 |
+
|
223 |
+
/**
|
224 |
+
* Catch the edit schedule form
|
225 |
+
*
|
226 |
+
* Validate and either return errors or update the schedule
|
227 |
+
*/
|
228 |
+
function hmnkp_edit_schedule_submit() {
|
229 |
+
|
230 |
+
if ( empty( $_GET['hmbkp_schedule_id'] ) )
|
231 |
+
return;
|
232 |
+
|
233 |
+
$schedule = new HMBKP_Scheduled_Backup( esc_attr( $_GET['hmbkp_schedule_id'] ) );
|
234 |
+
|
235 |
+
$errors = array();
|
236 |
+
|
237 |
+
if ( isset( $_GET['hmbkp_schedule_type'] ) ) {
|
238 |
+
|
239 |
+
if ( ! trim( $_GET['hmbkp_schedule_type'] ) )
|
240 |
+
$errors['hmbkp_schedule_type'] = __( 'Backup type cannot be empty', 'hmbkp' );
|
241 |
+
|
242 |
+
elseif ( ! in_array( $_GET['hmbkp_schedule_type'], array( 'complete', 'file', 'database' ) ) )
|
243 |
+
$errors['hmbkp_schedule_type'] = __( 'Invalid backup type', 'hmbkp' );
|
244 |
+
|
245 |
+
else
|
246 |
+
$schedule->set_type( $_GET['hmbkp_schedule_type'] );
|
247 |
+
|
248 |
+
}
|
249 |
+
|
250 |
+
if ( isset( $_GET['hmbkp_schedule_reoccurrence'] ) ) {
|
251 |
+
|
252 |
+
if ( empty( $_GET['hmbkp_schedule_reoccurrence'] ) )
|
253 |
+
$errors['hmbkp_schedule_reoccurrence'] = __( 'Schedule cannot be empty', 'hmbkp' );
|
254 |
+
|
255 |
+
elseif ( ! in_array( $_GET['hmbkp_schedule_reoccurrence'], array_keys( wp_get_schedules() ) ) && $_GET['hmbkp_schedule_reoccurrence'] !== 'manually' )
|
256 |
+
$errors['hmbkp_schedule_reoccurrence'] = __( 'Invalid schedule', 'hmbkp' );
|
257 |
+
|
258 |
+
else
|
259 |
+
$schedule->set_reoccurrence( $_GET['hmbkp_schedule_reoccurrence'] );
|
260 |
+
|
261 |
+
}
|
262 |
+
|
263 |
+
if ( isset( $_GET['hmbkp_schedule_max_backups'] ) ) {
|
264 |
+
|
265 |
+
if ( empty( $_GET['hmbkp_schedule_max_backups'] ) )
|
266 |
+
$errors['hmbkp_schedule_max_backups'] = __( 'Max backups can\'t be empty', 'hmbkp' );
|
267 |
+
|
268 |
+
elseif ( ! is_numeric( $_GET['hmbkp_schedule_max_backups'] ) )
|
269 |
+
$errors['hmbkp_schedule_max_backups'] = __( 'Max backups must be a number', 'hmbkp' );
|
270 |
+
|
271 |
+
elseif ( ! ( $_GET['hmbkp_schedule_max_backups'] >= 1 ) )
|
272 |
+
$errors['hmbkp_schedule_max_backups'] = __( 'Max backups must be greater than 0', 'hmbkp' );
|
273 |
+
|
274 |
+
else
|
275 |
+
$schedule->set_max_backups( (int) $_GET['hmbkp_schedule_max_backups'] );
|
276 |
+
|
277 |
+
$schedule->delete_old_backups();
|
278 |
+
|
279 |
+
}
|
280 |
+
|
281 |
+
foreach ( HMBKP_Services::get_services( $schedule ) as $service )
|
282 |
+
$errors = array_merge( $errors, $service->save() );
|
283 |
+
|
284 |
+
$schedule->save();
|
285 |
+
|
286 |
+
if ( $errors )
|
287 |
+
echo json_encode( $errors );
|
288 |
+
|
289 |
+
exit;
|
290 |
+
|
291 |
+
}
|
292 |
+
add_action( 'wp_ajax_hmnkp_edit_schedule_submit', 'hmnkp_edit_schedule_submit' );
|
293 |
+
|
294 |
+
|
295 |
+
/**
|
296 |
+
* Add an exclude rule
|
297 |
+
*
|
298 |
+
* @access public
|
299 |
+
* @return void
|
300 |
+
*/
|
301 |
+
function hmbkp_add_exclude_rule() {
|
302 |
+
|
303 |
+
$schedule = new HMBKP_Scheduled_Backup( esc_attr( $_POST['hmbkp_schedule_id'] ) );
|
304 |
+
|
305 |
+
$schedule->set_excludes( $_POST['hmbkp_exclude_rule'], true );
|
306 |
+
|
307 |
+
$schedule->save();
|
308 |
+
|
309 |
+
include( HMBKP_PLUGIN_PATH . '/admin/schedule-form-excludes.php' );
|
310 |
+
|
311 |
+
exit;
|
312 |
+
|
313 |
+
}
|
314 |
+
add_action( 'wp_ajax_hmbkp_add_exclude_rule', 'hmbkp_add_exclude_rule' );
|
315 |
+
|
316 |
+
|
317 |
+
/**
|
318 |
+
* Delete an exclude rule
|
319 |
+
*
|
320 |
+
* @access public
|
321 |
+
* @return void
|
322 |
+
*/
|
323 |
+
function hmbkp_delete_exclude_rule() {
|
324 |
+
|
325 |
+
$schedule = new HMBKP_Scheduled_Backup( esc_attr( $_POST['hmbkp_schedule_id'] ) );
|
326 |
+
|
327 |
+
$excludes = $schedule->get_excludes();
|
328 |
+
|
329 |
+
$schedule->set_excludes( array_diff( $excludes, (array) $_POST['hmbkp_exclude_rule'] ) );
|
330 |
+
|
331 |
+
$schedule->save();
|
332 |
+
|
333 |
+
include( HMBKP_PLUGIN_PATH . '/admin/schedule-form-excludes.php' );
|
334 |
+
|
335 |
+
exit;
|
336 |
+
|
337 |
+
}
|
338 |
+
add_action( 'wp_ajax_hmbkp_delete_exclude_rule', 'hmbkp_delete_exclude_rule' );
|
339 |
+
|
340 |
+
|
341 |
+
/**
|
342 |
+
* Ajax action for previewing an exclude rule.
|
343 |
+
*
|
344 |
+
* @access public
|
345 |
+
* @return void
|
346 |
+
*/
|
347 |
+
function hmbkp_preview_exclude_rule() {
|
348 |
+
|
349 |
+
if ( ! empty( $_POST['hmbkp_schedule_id'] ) )
|
350 |
+
$schedule = new HMBKP_Scheduled_Backup( $_POST['hmbkp_schedule_id'] );
|
351 |
+
|
352 |
+
if ( ! empty( $_POST['hmbkp_schedule_excludes'] ) )
|
353 |
+
$excludes = explode( ',', $_POST['hmbkp_schedule_excludes'] );
|
354 |
+
|
355 |
+
if ( ! empty( $_POST['hmbkp_file_method'] ) )
|
356 |
+
$file_method = $_POST['hmbkp_file_method'];
|
357 |
+
|
358 |
+
hmbkp_file_list( $schedule, $excludes, $file_method );
|
359 |
+
|
360 |
+
foreach( $schedule->get_excluded_files() as $key => $excluded_file )
|
361 |
+
if ( strpos( $excluded_file, $schedule->get_path() ) === false )
|
362 |
+
$excluded_files[] = $excluded_file;
|
363 |
+
|
364 |
+
if ( ! empty( $excluded_files) ) { ?>
|
365 |
+
|
366 |
+
<p><?php printf( _n( '%s matches 1 file.', '%1$s matches %2$d files.', count( $excluded_files ), 'hmbkp' ), '<code>' . implode( '</code>, <code>', $excludes ) . '</code>', count( $excluded_files ) ); ?></p>
|
367 |
+
|
368 |
+
<?php } else { ?>
|
369 |
+
|
370 |
+
<p><?php printf( __( '%s didn\'t match any files.', 'hmbkp' ), '<code>' . implode( '</code>, <code>', $excludes ) . '</code>' ); ?></p>
|
371 |
+
|
372 |
+
<?php } ?>
|
373 |
+
|
374 |
+
<p><button type="button" class="button-primary hmbkp_save_exclude_rule"><?php _e( 'Exclude', 'hmbkp' ); ?></button> <button type="button" class="button-secondary hmbkp_cancel_save_exclude_rule"><?php _e( 'Cancel', 'hmbkp' ); ?></button></p>
|
375 |
+
|
376 |
+
<?php exit;
|
377 |
+
|
378 |
+
}
|
379 |
+
add_action( 'wp_ajax_hmbkp_file_list', 'hmbkp_preview_exclude_rule', 10, 0 );
|
380 |
+
|
381 |
+
/**
|
382 |
+
* Handles changes in the defined Constants
|
383 |
+
* that users can define to control advanced
|
384 |
+
* settings
|
385 |
+
*/
|
386 |
+
function hmbkp_constant_changes() {
|
387 |
+
|
388 |
+
// If a custom backup path has been set or changed
|
389 |
+
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH && HM_Backup::conform_dir( HMBKP_PATH ) !== ( $from = HM_Backup::conform_dir( get_option( 'hmbkp_path' ) ) ) )
|
390 |
+
hmbkp_path_move( $from, HMBKP_PATH );
|
391 |
+
|
392 |
+
// If a custom backup path has been removed
|
393 |
+
if ( ( ( defined( 'HMBKP_PATH' ) && ! HMBKP_PATH ) || ! defined( 'HMBKP_PATH' ) && HM_Backup::conform_dir( hmbkp_path_default() ) != ( $from = HM_Backup::conform_dir( get_option( 'hmbkp_path' ) ) ) ) )
|
394 |
+
hmbkp_path_move( $from, hmbkp_path_default() );
|
395 |
+
|
396 |
+
// If the custom path has changed and the new directory isn't writable
|
397 |
+
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH && HM_Backup::conform_dir( HMBKP_PATH ) != ( $from = HM_Backup::conform_dir( get_option( 'hmbkp_path' ) ) ) && $from != hmbkp_path_default() && !is_writable( HMBKP_PATH ) && is_dir( $from ) )
|
398 |
+
hmbkp_path_move( $from, hmbkp_path_default() );
|
399 |
+
|
400 |
+
}
|
admin/backups.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php $schedules = new HMBKP_Schedules; ?>
|
2 |
+
|
3 |
+
<div>
|
4 |
+
|
5 |
+
<ul class="subsubsub">
|
6 |
+
|
7 |
+
<?php foreach ( $schedules->get_schedules() as $schedule ) : ?>
|
8 |
+
|
9 |
+
<li><a<?php if ( ! empty ( $_GET['hmbkp_schedule_id'] ) && $schedule->get_id() == $_GET['hmbkp_schedule_id'] ) { ?> class="current"<?php } ?> href="<?php echo esc_url( add_query_arg( 'hmbkp_schedule_id', $schedule->get_id(), HMBKP_ADMIN_URL ) ); ?> "><?php echo esc_attr( $schedule->get_name() ); ?> <span class="count">(<?php echo count( $schedule->get_backups() ); ?>)</span></a></li>
|
10 |
+
|
11 |
+
<?php endforeach; ?>
|
12 |
+
|
13 |
+
<li><a class="fancybox" href="<?php echo esc_url( add_query_arg( array( 'action' => 'hmbkp_add_schedule_load' ), admin_url( 'admin-ajax.php' ) ) ); ?>"> + <?php _e( 'add schedule', 'hmbkp' ); ?></a></li>
|
14 |
+
|
15 |
+
</ul>
|
16 |
+
|
17 |
+
<?php if ( ! empty( $_GET['hmbkp_schedule_id'] ) )
|
18 |
+
$schedule = new HMBKP_Scheduled_Backup( $_GET['hmbkp_schedule_id'] );
|
19 |
+
|
20 |
+
else
|
21 |
+
$schedule = reset( $schedules->get_schedules() );
|
22 |
+
|
23 |
+
if ( ! $schedule )
|
24 |
+
return; ?>
|
25 |
+
|
26 |
+
<div data-hmbkp-schedule-id="<?php echo esc_attr( $schedule->get_id() ); ?>" class="hmbkp_schedule">
|
27 |
+
|
28 |
+
<?php require( HMBKP_PLUGIN_PATH . '/admin/schedule.php' ); ?>
|
29 |
+
|
30 |
+
<table class="widefat">
|
31 |
+
|
32 |
+
<thead>
|
33 |
+
|
34 |
+
<tr>
|
35 |
+
|
36 |
+
<th scope="col"><?php printf( _n( '1 backup completed', '%d backups completed', count( $schedule->get_backups() ), 'hmbkp' ), count( $schedule->get_backups() ) ); ?></th>
|
37 |
+
<th scope="col"><?php _e( 'Size', 'hmbkp' ); ?></th>
|
38 |
+
<th scope="col"><?php _e( 'Type', 'hmbkp' ); ?></th>
|
39 |
+
<th scope="col"><?php _e( 'Actions', 'hmbkp' ); ?></th>
|
40 |
+
|
41 |
+
</tr>
|
42 |
+
|
43 |
+
</thead>
|
44 |
+
|
45 |
+
<tbody>
|
46 |
+
|
47 |
+
<?php if ( $schedule->get_backups() ) :
|
48 |
+
|
49 |
+
foreach ( $schedule->get_backups() as $file ) :
|
50 |
+
|
51 |
+
if ( ! file_exists( $file ) )
|
52 |
+
continue;
|
53 |
+
|
54 |
+
hmbkp_get_backup_row( $file, $schedule );
|
55 |
+
|
56 |
+
endforeach;
|
57 |
+
|
58 |
+
else : ?>
|
59 |
+
|
60 |
+
<tr>
|
61 |
+
|
62 |
+
<td class="hmbkp-no-backups" colspan="3"><?php _e( 'This is where your backups will appear once you have one.', 'hmbkp' ); ?></td>
|
63 |
+
|
64 |
+
</tr>
|
65 |
+
|
66 |
+
<?php endif; ?>
|
67 |
+
|
68 |
+
</tbody>
|
69 |
+
|
70 |
+
</table>
|
71 |
+
|
72 |
+
</div>
|
73 |
+
|
74 |
+
</div>
|
admin.constants.php → admin/constants.php
RENAMED
@@ -13,21 +13,6 @@
|
|
13 |
<dt<?php if ( defined( 'HMBKP_ZIP_PATH' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_ZIP_PATH</code></dt>
|
14 |
<dd><p><?php printf( __( 'The path to your %1$s executable. Will be used to zip up your %2$s and %3$s if available.', 'hmbkp' ), '<code>zip</code>', '<code>' . __( 'files', 'hmbkp' ) . '</code>', '<code>' . __( 'database', 'hmbkp' ) . '</code>' ); ?><p class="example"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_ZIP_PATH', '/opt/local/bin/zip' );</code></p></dd>
|
15 |
|
16 |
-
<dt<?php if ( defined( 'HMBKP_DISABLE_AUTOMATIC_BACKUP' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_DISABLE_AUTOMATIC_BACKUP</code></dt>
|
17 |
-
<dd><p><?php printf( __( 'Completely disables the automatic back up. You can still back up using the "Back Up Now" button. Defaults to %s.', 'hmbkp' ), '<code>(bool) false</code>' ); ?><p class="example"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_DISABLE_AUTOMATIC_BACKUP', true );</code></p></dd>
|
18 |
-
|
19 |
-
<dt<?php if ( defined( 'HMBKP_MAX_BACKUPS' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_MAX_BACKUPS</code></dt>
|
20 |
-
<dd><p><?php printf( __( 'Number of backups to keep, older backups will be deleted automatically when a new backup is completed. Defaults to %s.', 'hmbkp' ), '<code>(int) 10</code>' ); ?><p class="example"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_MAX_BACKUPS', 5 );</code></p></dd>
|
21 |
-
|
22 |
-
<dt<?php if ( defined( 'HMBKP_FILES_ONLY' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_FILES_ONLY</code></dt>
|
23 |
-
<dd><p><?php printf( __( 'Backup %1$s only, your %2$s won\'t be backed up. Defaults to %3$s.', 'hmbkp' ), '<code>' . __( 'files', 'hmbkp' ) . '</code>', '<code>' . __( 'database', 'hmbkp' ) . '</code>', '<code>(bool) false</code>' ); ?><p class="example"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_FILES_ONLY', true );</code></p></dd>
|
24 |
-
|
25 |
-
<dt<?php if ( defined( 'HMBKP_DATABASE_ONLY' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_DATABASE_ONLY</code></dt>
|
26 |
-
<dd><p><?php printf( __( 'Backup %1$s only, your %2$s won\'t be backed up. Defaults to %3$s.', 'hmbkp' ), '<code>' . __( 'database', 'hmbkp' ) . '</code>', '<code>' . __( 'files', 'hmbkp' ) . '</code>', '<code>(bool) false</code>' ); ?><p class="example"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_DATABASE_ONLY', true );</code></p></dd>
|
27 |
-
|
28 |
-
<dt<?php if ( defined( 'HMBKP_DAILY_SCHEDULE_TIME' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_DAILY_SCHEDULE_TIME</code></dt>
|
29 |
-
<dd><p><?php printf( __( 'The time that the daily back up should run. Defaults to %s.', 'hmbkp' ), '<code>23:00</code>' ); ?><p class="example"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_DAILY_SCHEDULE_TIME', '07:30' );</code></p></dd>
|
30 |
-
|
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"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_EMAIL', 'email@example.com' );</code></p></dd>
|
33 |
|
@@ -38,7 +23,7 @@
|
|
38 |
<dd><p><?php printf( __( 'The capability to use when calling %1$s. Defaults to %2$s.', 'hmbkp' ), '<code>add_menu_page</code>', '<code>manage_options</code>' ); ?><p class="example"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_CAPABILITY', 'edit_posts' );</code></p></dd>
|
39 |
|
40 |
<dt<?php if ( defined( 'HMBKP_ROOT' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_ROOT</code></dt>
|
41 |
-
<dd><p><?php printf( __( 'The root directory that is backed up. Defaults to %s.', 'hmbkp' ), '<code>' .
|
42 |
|
43 |
</dl>
|
44 |
|
13 |
<dt<?php if ( defined( 'HMBKP_ZIP_PATH' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_ZIP_PATH</code></dt>
|
14 |
<dd><p><?php printf( __( 'The path to your %1$s executable. Will be used to zip up your %2$s and %3$s if available.', 'hmbkp' ), '<code>zip</code>', '<code>' . __( 'files', 'hmbkp' ) . '</code>', '<code>' . __( 'database', 'hmbkp' ) . '</code>' ); ?><p class="example"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_ZIP_PATH', '/opt/local/bin/zip' );</code></p></dd>
|
15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16 |
<dt<?php if ( defined( 'HMBKP_EMAIL' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_EMAIL</code></dt>
|
17 |
<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"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_EMAIL', 'email@example.com' );</code></p></dd>
|
18 |
|
23 |
<dd><p><?php printf( __( 'The capability to use when calling %1$s. Defaults to %2$s.', 'hmbkp' ), '<code>add_menu_page</code>', '<code>manage_options</code>' ); ?><p class="example"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_CAPABILITY', 'edit_posts' );</code></p></dd>
|
24 |
|
25 |
<dt<?php if ( defined( 'HMBKP_ROOT' ) ) { ?> class="hmbkp_active"<?php } ?>><code>HMBKP_ROOT</code></dt>
|
26 |
+
<dd><p><?php printf( __( 'The root directory that is backed up. Defaults to %s.', 'hmbkp' ), '<code>' . HM_Backup::get_home_path() . '</code>' ); ?><p class="example"><?php _e( 'e.g.', 'hmbkp' ); ?> <code>define( 'HMBKP_ROOT', ABSPATH . 'wp/' );</code></p></dd>
|
27 |
|
28 |
</dl>
|
29 |
|
admin.menus.php → admin/menu.php
RENAMED
@@ -18,7 +18,7 @@ add_action( 'admin_menu', 'hmbkp_admin_menu' );
|
|
18 |
* @return null
|
19 |
*/
|
20 |
function hmbkp_manage_backups() {
|
21 |
-
require_once( HMBKP_PLUGIN_PATH . '/admin
|
22 |
}
|
23 |
|
24 |
/**
|
@@ -31,12 +31,12 @@ function hmbkp_manage_backups() {
|
|
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.
|
@@ -47,11 +47,15 @@ add_filter('plugin_action_links', 'hmbkp_plugin_action_link', 10, 2 );
|
|
47 |
*/
|
48 |
function hmbkp_contextual_help() {
|
49 |
|
|
|
|
|
|
|
|
|
50 |
require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
|
51 |
|
52 |
if ( ! $plugin = get_transient( 'hmbkp_plugin_data' ) ) {
|
53 |
|
54 |
-
$plugin = plugins_api( 'plugin_information', array( 'slug' =>
|
55 |
|
56 |
// Cache for one day
|
57 |
set_transient( 'hmbkp_plugin_data', $plugin, 86400 );
|
@@ -62,16 +66,12 @@ function hmbkp_contextual_help() {
|
|
62 |
|
63 |
// Check if help is for the right version.
|
64 |
if ( ! empty( $plugin->version ) && version_compare( HMBKP_VERSION, $plugin->version, '!=' ) )
|
65 |
-
$warning = sprintf( '<div id="message" class="updated inline"><p><strong>' . __( 'You are not using the latest stable version of BackUpWordPress', 'hmbkp' ) . '</strong> — ' . __( 'The information below is for version %1$s. View the %2$s file for help specific to version %3$s.', 'hmbkp' ) . '</p></div>', '<code>' . $plugin->version . '</code>', '<code>readme.txt</code>', '<code>' . HMBKP_VERSION . '</code>' );
|
66 |
|
67 |
ob_start();
|
68 |
-
require_once( HMBKP_PLUGIN_PATH . '/admin
|
69 |
$constants = ob_get_clean();
|
70 |
|
71 |
-
// Pre WordPress 3.3 compat
|
72 |
-
if ( ! method_exists( get_current_screen(), 'add_help_tab' ) )
|
73 |
-
return;
|
74 |
-
|
75 |
get_current_screen()->add_help_tab( array( 'title' => __( 'FAQ', 'hmbkp' ), 'id' => 'hmbkp_faq', 'content' => $warning . $plugin->sections['faq'] ) );
|
76 |
get_current_screen()->add_help_tab( array( 'title' => __( 'Constants', 'hmbkp' ), 'id' => 'hmbkp_constants', 'content' => $warning . $constants ) );
|
77 |
|
18 |
* @return null
|
19 |
*/
|
20 |
function hmbkp_manage_backups() {
|
21 |
+
require_once( HMBKP_PLUGIN_PATH . '/admin/page.php' );
|
22 |
}
|
23 |
|
24 |
/**
|
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=' . esc_attr( 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.
|
47 |
*/
|
48 |
function hmbkp_contextual_help() {
|
49 |
|
50 |
+
// Pre WordPress 3.3 compat
|
51 |
+
if ( ! method_exists( get_current_screen(), 'add_help_tab' ) )
|
52 |
+
return;
|
53 |
+
|
54 |
require_once( ABSPATH . 'wp-admin/includes/plugin-install.php' );
|
55 |
|
56 |
if ( ! $plugin = get_transient( 'hmbkp_plugin_data' ) ) {
|
57 |
|
58 |
+
$plugin = plugins_api( 'plugin_information', array( 'slug' => HMBKP_PLUGIN_SLUG ) );
|
59 |
|
60 |
// Cache for one day
|
61 |
set_transient( 'hmbkp_plugin_data', $plugin, 86400 );
|
66 |
|
67 |
// Check if help is for the right version.
|
68 |
if ( ! empty( $plugin->version ) && version_compare( HMBKP_VERSION, $plugin->version, '!=' ) )
|
69 |
+
$warning = sprintf( '<div id="message" class="updated inline"><p><strong>' . __( 'You are not using the latest stable version of BackUpWordPress', 'hmbkp' ) . '</strong> — ' . __( 'The information below is for version %1$s. View the %2$s file for help specific to version %3$s.', 'hmbkp' ) . '</p></div>', '<code>' . esc_attr( $plugin->version ) . '</code>', '<code>readme.txt</code>', '<code>' . esc_attr( HMBKP_VERSION ) . '</code>' );
|
70 |
|
71 |
ob_start();
|
72 |
+
require_once( HMBKP_PLUGIN_PATH . '/admin/constants.php' );
|
73 |
$constants = ob_get_clean();
|
74 |
|
|
|
|
|
|
|
|
|
75 |
get_current_screen()->add_help_tab( array( 'title' => __( 'FAQ', 'hmbkp' ), 'id' => 'hmbkp_faq', 'content' => $warning . $plugin->sections['faq'] ) );
|
76 |
get_current_screen()->add_help_tab( array( 'title' => __( 'Constants', 'hmbkp' ), 'id' => 'hmbkp_constants', 'content' => $warning . $constants ) );
|
77 |
|
admin/page.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div class="wrap">
|
2 |
+
|
3 |
+
<?php screen_icon( HMBKP_PLUGIN_SLUG ); ?>
|
4 |
+
|
5 |
+
<h2><?php _e( 'Manage Backups', 'hmbkp' ); ?></h2>
|
6 |
+
|
7 |
+
<?php if ( hmbkp_possible() ) : ?>
|
8 |
+
|
9 |
+
<?php include_once( HMBKP_PLUGIN_PATH . '/admin/backups.php' ); ?>
|
10 |
+
|
11 |
+
<?php else : ?>
|
12 |
+
|
13 |
+
<p><strong><?php _e( 'You need to fix the issues detailed above before BackUpWordPress can start.', 'hmbkp' ); ?></strong></p>
|
14 |
+
|
15 |
+
<?php endif; ?>
|
16 |
+
|
17 |
+
<p class="howto"><?php printf( __( 'If you need help getting things working you are more than welcome to email us at %s and we\'ll do what we can.', 'hmbkp' ), '<a href="mailto:support@hmn.md">support@hmn.md</a>' ); ?></p>
|
18 |
+
|
19 |
+
</div>
|
admin/schedule-form-excludes.php
ADDED
@@ -0,0 +1,123 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<form method="post" class="hmbkp-form">
|
2 |
+
|
3 |
+
<input type="hidden" name="hmbkp_schedule_id" value="<?php echo esc_attr( $schedule->get_id() ); ?>" />
|
4 |
+
|
5 |
+
<fieldset class="hmbkp-edit-schedule-excludes-form">
|
6 |
+
|
7 |
+
<legend><?php _e( 'Manage Excludes', 'hmbkp' ); ?></legend>
|
8 |
+
|
9 |
+
<div class="hmbkp_add_exclude_rule">
|
10 |
+
|
11 |
+
<label for="hmbkp-new-exclude-rule">
|
12 |
+
|
13 |
+
<?php _e( 'New Exclude Rule', 'hmbkp' ); ?>
|
14 |
+
|
15 |
+
<input id="hmbkp-new-exclude-rule" type="text" class="code" placeholder=".git/, *.mp3, wp-content/uploads/" />
|
16 |
+
|
17 |
+
<button type="button" class="button-secondary hmbkp_preview_exclude_rule"><?php _e( 'Preview', 'hmbkp' ); ?></button>
|
18 |
+
|
19 |
+
</label>
|
20 |
+
|
21 |
+
</div>
|
22 |
+
|
23 |
+
<table class="widefat fixed">
|
24 |
+
|
25 |
+
<thead>
|
26 |
+
<tr>
|
27 |
+
<th><?php _e( 'Exclude Rules', 'hmbkp' ); ?></th>
|
28 |
+
</tr>
|
29 |
+
</thead>
|
30 |
+
|
31 |
+
<tbody>
|
32 |
+
|
33 |
+
<?php foreach( $schedule->get_excludes() as $key => $exclude ) : ?>
|
34 |
+
|
35 |
+
<tr>
|
36 |
+
<td data-hmbkp-exclude-rule="<?php echo esc_attr( $exclude ); ?>">
|
37 |
+
|
38 |
+
<span class="code"><?php echo esc_attr( str_ireplace( untrailingslashit( $schedule->get_root() ), '', $exclude ) ); ?></span>
|
39 |
+
|
40 |
+
<?php if ( strpos( $schedule->get_path(), untrailingslashit( $exclude ) ) !== false ) : ?>
|
41 |
+
|
42 |
+
<span class="reason"><?php _e( 'default', 'hmbkp' ); ?></span>
|
43 |
+
|
44 |
+
<?php elseif ( defined( 'HMBKP_EXCLUDE' ) && strpos( HMBKP_EXCLUDE, $exclude ) !== false ) : ?>
|
45 |
+
|
46 |
+
<span class="reason"><?php _e( 'defined', 'hmbkp' ); ?></span>
|
47 |
+
|
48 |
+
<?php else : ?>
|
49 |
+
|
50 |
+
<a href="#" class="delete-action"><?php _e( 'Remove', 'hmbkp' ); ?></a>
|
51 |
+
|
52 |
+
<?php endif; ?>
|
53 |
+
|
54 |
+
</td>
|
55 |
+
</tr>
|
56 |
+
|
57 |
+
<?php endforeach; ?>
|
58 |
+
|
59 |
+
</tbody>
|
60 |
+
|
61 |
+
</table>
|
62 |
+
|
63 |
+
<div class="hmbkp-tabs">
|
64 |
+
|
65 |
+
<ul class="subsubsub">
|
66 |
+
|
67 |
+
<?php if ( $schedule->get_excluded_files() ) : ?>
|
68 |
+
|
69 |
+
<li><a href="#hmbkp_excluded_files"><?php _e( 'Excluded', 'hmbkp' ); ?></a>(<?php echo count( $schedule->get_excluded_files() ); ?>)</li>
|
70 |
+
|
71 |
+
<?php endif; ?>
|
72 |
+
|
73 |
+
<li><a href="#hmbkp_included_files"><?php _e( 'Included', 'hmbkp' ); ?></a>(<?php echo count( $schedule->get_included_files() ); ?>)</li>
|
74 |
+
|
75 |
+
<?php if ( $schedule->get_unreadable_files() ) : ?>
|
76 |
+
|
77 |
+
<li><a href="#hmbkp_unreadable_files"><?php _e( 'Unreadable', 'hmbkp' ); ?></a>(<?php echo count( $schedule->get_unreadable_files() ); ?>)</li>
|
78 |
+
|
79 |
+
<?php endif; ?>
|
80 |
+
|
81 |
+
</ul>
|
82 |
+
|
83 |
+
<?php if ( $schedule->get_excluded_files() ) : ?>
|
84 |
+
|
85 |
+
<div id="hmbkp_excluded_files">
|
86 |
+
|
87 |
+
<?php hmbkp_file_list( $schedule, null, 'get_excluded_files' ); ?>
|
88 |
+
|
89 |
+
</div>
|
90 |
+
|
91 |
+
<?php endif; ?>
|
92 |
+
|
93 |
+
<div id="hmbkp_included_files">
|
94 |
+
|
95 |
+
<?php hmbkp_file_list( $schedule, null, 'get_included_files' ); ?>
|
96 |
+
|
97 |
+
</div>
|
98 |
+
|
99 |
+
<?php if ( $schedule->get_unreadable_files() ) : ?>
|
100 |
+
|
101 |
+
<div id="hmbkp_unreadable_files">
|
102 |
+
|
103 |
+
<?php hmbkp_file_list( $schedule, null, 'get_unreadable_files' ); ?>
|
104 |
+
|
105 |
+
<p class="description"><?php _e( 'Unreadable files can\'t be backed up', 'hmbkp' ); ?></p>
|
106 |
+
|
107 |
+
</div>
|
108 |
+
|
109 |
+
<?php endif; ?>
|
110 |
+
|
111 |
+
<p><?php printf( __( 'Your site is %s. Backups will be compressed and so will be smaller.', 'hmbkp' ), '<code>' . $schedule->get_filesize( false ) . '</code>' ); ?></p>
|
112 |
+
|
113 |
+
</div>
|
114 |
+
|
115 |
+
<p class="submit">
|
116 |
+
|
117 |
+
<button type="submit" class="button-primary"><?php _e( 'Close', 'hmbkp' ); ?></button>
|
118 |
+
|
119 |
+
</p>
|
120 |
+
|
121 |
+
</fieldset>
|
122 |
+
|
123 |
+
</form>
|
admin/schedule-form.php
ADDED
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<form method="post" class="hmbkp-form" novalidate data-schedule-action="<?php if ( isset( $is_new_schedule ) ) { ?>add<?php } else { ?>edit<?php } ?>">
|
2 |
+
|
3 |
+
<input type="hidden" name="hmbkp_schedule_id" value="<?php echo esc_attr( $schedule->get_id() ); ?>" />
|
4 |
+
|
5 |
+
<fieldset class="hmbkp-edit-schedule-form">
|
6 |
+
|
7 |
+
<legend><?php _e( 'Schedule Settings', 'hmbkp' ); ?></legend>
|
8 |
+
|
9 |
+
<label>
|
10 |
+
|
11 |
+
<?php _e( 'Backup', 'hmbkp' ); ?>
|
12 |
+
|
13 |
+
<select name="hmbkp_schedule_type" id="hmbkp_schedule_type">
|
14 |
+
<option<?php selected( $schedule->get_type(), 'complete'); ?> value="complete"><?php _e( 'Both Database & files', 'hmbkp' ); ?></option>
|
15 |
+
<option<?php selected( $schedule->get_type(), 'file'); ?> value="file"><?php _e( 'Files only', 'hmbkp' ); ?></option>
|
16 |
+
<option<?php selected( $schedule->get_type(), 'database'); ?> value="database"><?php _e( 'Database only', 'hmbkp' ); ?></option>
|
17 |
+
</select>
|
18 |
+
|
19 |
+
</label>
|
20 |
+
|
21 |
+
<label>
|
22 |
+
|
23 |
+
<?php _e( 'Schedule', 'hmbkp' ); ?>
|
24 |
+
|
25 |
+
<select name="hmbkp_schedule_reoccurrence" id="hmbkp_schedule_reoccurrence">
|
26 |
+
|
27 |
+
<option value="manually"><?php _e( 'Manual Only', 'hmbkp' ); ?></option>
|
28 |
+
|
29 |
+
<?php foreach( wp_get_schedules() as $cron_schedule => $cron_details ) : ?>
|
30 |
+
|
31 |
+
<option<?php selected( $schedule->get_reoccurrence(), $cron_schedule ); ?> value="<?php echo esc_attr( $cron_schedule ); ?>"><?php echo esc_attr( $cron_details['display'] ); ?></option>
|
32 |
+
|
33 |
+
<?php endforeach; ?>
|
34 |
+
|
35 |
+
</select>
|
36 |
+
|
37 |
+
</label>
|
38 |
+
|
39 |
+
<label>
|
40 |
+
|
41 |
+
<?php _e( 'Number of backups to store on this server', 'hmbkp' ); ?>
|
42 |
+
|
43 |
+
<input type="number" name="hmbkp_schedule_max_backups" min="1" step="1" value="<?php echo esc_attr( $schedule->get_max_backups() ); ?>" />
|
44 |
+
|
45 |
+
<p class="description"><?php _e( 'The number of previous backups to store on the server. past this limit older backups will be deleted automatically.', 'hmbkp' ); ?></p>
|
46 |
+
|
47 |
+
</label>
|
48 |
+
|
49 |
+
<?php foreach ( HMBKP_Services::get_services( $schedule ) as $service )
|
50 |
+
$service->field(); ?>
|
51 |
+
|
52 |
+
<p class="submit">
|
53 |
+
|
54 |
+
<button type="submit" class="button-primary"><?php _e( 'Update', 'hmbkp' ); ?></button>
|
55 |
+
|
56 |
+
</p>
|
57 |
+
|
58 |
+
</fieldset>
|
59 |
+
|
60 |
+
</form>
|
admin/schedule.php
ADDED
@@ -0,0 +1,100 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
// Calculated filesize
|
4 |
+
$filesize = $schedule->is_filesize_cached() || isset( $recalculate_filesize ) ? '<code title="' . __( 'Backups will be compressed and should be smaller than this.', 'hmbkp' ) . '">' . esc_attr( $schedule->get_filesize() ) . '</code>' : '<code class="calculating" title="' . __( 'this shouldn\'t take long…', 'hmbkp' ) . '">' . __( 'calculating the size of your site…', 'hmbkp' ) . '</code>';
|
5 |
+
|
6 |
+
// Backup Type
|
7 |
+
$type = strtolower( hmbkp_human_get_type( $schedule->get_type() ) );
|
8 |
+
|
9 |
+
// Backup Time
|
10 |
+
$day = date_i18n( 'l', $schedule->get_next_occurrence() );
|
11 |
+
|
12 |
+
$next_backup = 'title="' . sprintf( __( 'The next backup will be on %1$s at %2$s', 'hmbkp' ), date_i18n( get_option( 'date_format' ), $schedule->get_next_occurrence() ), date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence() ) ) . '"';
|
13 |
+
|
14 |
+
// Backup Re-occurrence
|
15 |
+
switch ( $schedule->get_reoccurrence() ) :
|
16 |
+
|
17 |
+
case 'hourly' :
|
18 |
+
|
19 |
+
$reoccurrence = date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence() ) === '00' ? sprintf( __( 'hourly on the hour', 'hmbkp' ) ) : sprintf( __( 'hourly at %s minutes past the hour', 'hmbkp' ), '<span ' . $next_backup . '>' . str_replace( '0', '', date_i18n( 'i', $schedule->get_next_occurrence() ) ) ) . '</span>';
|
20 |
+
|
21 |
+
break;
|
22 |
+
|
23 |
+
case 'daily' :
|
24 |
+
|
25 |
+
$reoccurrence = sprintf( __( 'daily at %s', 'hmbkp' ), '<span ' . $next_backup . '>' . date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence() ) . '</span>' );
|
26 |
+
|
27 |
+
break;
|
28 |
+
|
29 |
+
|
30 |
+
case 'twicedaily' :
|
31 |
+
|
32 |
+
$times[] = date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence() );
|
33 |
+
$times[] = date_i18n( get_option( 'time_format' ), strtotime( '+ 12 hours', $schedule->get_next_occurrence() ) );
|
34 |
+
|
35 |
+
sort( $times );
|
36 |
+
|
37 |
+
$reoccurrence = sprintf( __( 'every 12 hours at %1$s & %2$s', 'hmbkp' ), '<span ' . $next_backup . '>' . reset( $times ) . '</span>', '<span>' . end( $times ) ) . '</span>';
|
38 |
+
|
39 |
+
break;
|
40 |
+
|
41 |
+
case 'weekly' :
|
42 |
+
|
43 |
+
$reoccurrence = sprintf( __( 'weekly on %1$s at %2$s', 'hmbkp' ), '<span ' . $next_backup . '>' . $day . '</span>', '<span>' . date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence() ) . '</span>' );
|
44 |
+
|
45 |
+
break;
|
46 |
+
|
47 |
+
case 'fortnightly' :
|
48 |
+
|
49 |
+
$reoccurrence = sprintf( __( 'fortnightly on %1$s at %2$s', 'hmbkp' ), '<span ' . $next_backup . '>' . $day . '</span>', '<span>' . date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence() ) . '</span>' );
|
50 |
+
|
51 |
+
break;
|
52 |
+
|
53 |
+
|
54 |
+
case 'monthly' :
|
55 |
+
|
56 |
+
$reoccurrence = sprintf( __( 'on the %1$s of each month at %2$s', 'hmbkp' ), '<span ' . $next_backup . '>' . date_i18n( 'jS', $schedule->get_next_occurrence() ) . '</span>', '<span>' . date_i18n( get_option( 'time_format' ), $schedule->get_next_occurrence() ) . '</span>' );
|
57 |
+
|
58 |
+
break;
|
59 |
+
|
60 |
+
case 'manually' :
|
61 |
+
|
62 |
+
$reoccurrence = __( 'manually', 'hmbkp' );
|
63 |
+
|
64 |
+
break;
|
65 |
+
|
66 |
+
endswitch;
|
67 |
+
|
68 |
+
$server = '<span title="' . esc_attr( hmbkp_path() ) . '">' . __( 'this server', 'hmbkp' ) . '</span>';
|
69 |
+
|
70 |
+
// Backup to keep
|
71 |
+
switch ( $schedule->get_max_backups() ) :
|
72 |
+
|
73 |
+
case 1 :
|
74 |
+
|
75 |
+
$backup_to_keep = sprintf( __( 'store the only the last backup on %s', 'hmbkp' ), $server );
|
76 |
+
|
77 |
+
break;
|
78 |
+
|
79 |
+
case 0 :
|
80 |
+
|
81 |
+
$backup_to_keep = sprintf( __( 'don\'t store any backups on %s', 'hmbkp' ), $server );
|
82 |
+
|
83 |
+
break;
|
84 |
+
|
85 |
+
default :
|
86 |
+
|
87 |
+
$backup_to_keep = sprintf( __( 'store only the last %1$s backups on %2$s', 'hmbkp' ), esc_attr( $schedule->get_max_backups() ), $server );
|
88 |
+
|
89 |
+
endswitch;
|
90 |
+
|
91 |
+
foreach ( HMBKP_Services::get_services( $schedule ) as $file => $service )
|
92 |
+
$services[] = $service->display(); ?>
|
93 |
+
|
94 |
+
<div class="hmbkp-schedule-sentence<?php if ( $schedule->get_status() ) { ?> hmbkp-running<?php } ?>">
|
95 |
+
|
96 |
+
<?php printf( __( 'Backup my %1$s %2$s %3$s, %4$s. %5$s', 'hmbkp' ), $filesize, '<span>' . $type . '</span>', $reoccurrence, $backup_to_keep, implode( '. ', $services ) ); ?>
|
97 |
+
|
98 |
+
<?php hmbkp_schedule_actions( $schedule ); ?>
|
99 |
+
|
100 |
+
</div>
|
assets/fancyBox/CHANGELOG.md
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
fancyBox - Changelog
|
2 |
+
=========
|
3 |
+
|
4 |
+
### Version 2.0.5 - February 21, 2012
|
5 |
+
|
6 |
+
* Fixed #155 - easing for prev/next animations
|
7 |
+
* Fixed #153 - overriding "keys" options
|
8 |
+
* Fixed #147 - IE7 problem with #hash links
|
9 |
+
* Fixed #130 - changing dynamically data-fancybox-group
|
10 |
+
* Fixed #126 - obey minWidth/minHeight
|
11 |
+
* Fixed #118 - placement of loading icon and navigation arrows
|
12 |
+
* Fixed #101 - "index" option not working
|
13 |
+
* Fixed #94 - "orig" option not working
|
14 |
+
* Fixed #80 - does not work on IE6
|
15 |
+
* Fixed #72 - can't set overlay opacity to 0
|
16 |
+
* Fixed #63 - properly set gallery index
|
17 |
+
* New option "autoCenter" - toggles centering on window resize or scroll, disabled for mobile devices by default
|
18 |
+
* New option "autoResize" - toggles responsivity, disabled for mobile devices by default
|
19 |
+
* New option "preload" - number of images to preload
|
20 |
+
* New feature to target mobile/desktop browsers using CSS, see #108
|
21 |
+
* Changed ajax option defaults to "{ dataType: 'html', headers: { 'X-fancyBox': true } }", see #150 and #128
|
22 |
+
* Updated loading icon for IE7, IE8
|
23 |
+
* Calculates height of the iframe if 'autoSize' is set to 'true' and the iframe is on the same domain as the main page
|
24 |
+
|
25 |
+
### Version 2.0.4 - December 12, 2011
|
26 |
+
|
27 |
+
* Fixed #47 - fix overriding properties
|
28 |
+
* New option "position" to thumbnail and button helpers
|
29 |
+
|
30 |
+
|
31 |
+
### Version 2.0.3 - November 29, 2011
|
32 |
+
|
33 |
+
* Fixed #29 - broken elastic transitions
|
34 |
+
|
35 |
+
|
36 |
+
### Version 2.0.2 - November 28, 2011
|
37 |
+
|
38 |
+
* Fixed slidshow
|
39 |
+
* Fixed scrollbar issue when displayed a very tall image
|
40 |
+
* New option "nextClick" - navigate to next gallery item when user clicks the content
|
41 |
+
* New option "modal" - to disable navigation and closing
|
42 |
+
* Add 'metadata' plugin support
|
43 |
+
* Add ability to create groups using 'data-fancybox-group' attribute
|
44 |
+
* Updated manual usage to match earlier releases
|
45 |
+
|
46 |
+
|
47 |
+
### Version 2.0.1 - November 23, 2011
|
48 |
+
|
49 |
+
* Fixed keyboard events inside form elements
|
50 |
+
* Fixed manual usage
|
51 |
+
|
52 |
+
|
53 |
+
### Version 2.0.0 - November 21, 2011
|
54 |
+
|
55 |
+
First release - completely rewritten, many new features and updated graphics.
|
assets/fancyBox/README.md
ADDED
@@ -0,0 +1,199 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
fancyBox
|
2 |
+
========
|
3 |
+
|
4 |
+
fancyBox is a tool that offers a nice and elegant way to add zooming functionality for images, html content and multi-media on your webpages.
|
5 |
+
|
6 |
+
More information and examples: http://www.fancyapps.com/fancybox/
|
7 |
+
|
8 |
+
License: http://www.fancyapps.com/fancybox/#license
|
9 |
+
|
10 |
+
Copyright (c) 2012 Janis Skarnelis - janis@fancyapps.com
|
11 |
+
|
12 |
+
|
13 |
+
How to use
|
14 |
+
----------
|
15 |
+
|
16 |
+
To get started, download the plugin, unzip it and copy files to your website/application directory.
|
17 |
+
Load files in the <head> section of your HTML document. Make sure you also add the jQuery library.
|
18 |
+
|
19 |
+
<head>
|
20 |
+
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
|
21 |
+
<link rel="stylesheet" href="/fancybox/jquery.fancybox.css" type="text/css" media="screen" />
|
22 |
+
<script type="text/javascript" src="/fancybox/jquery.fancybox.pack.js"></script>
|
23 |
+
</head>
|
24 |
+
|
25 |
+
Create your links with a `title` if you want a title to be shown, and add a class:
|
26 |
+
|
27 |
+
<a href="large_image.jpg" class="fancybox" title="Sample title"><img src="small_image.jpg" /></a>
|
28 |
+
|
29 |
+
If you have a set of related items that you would like to group,
|
30 |
+
additionally include a group name in the `rel` (or `data-fancybox-group`) attribute:
|
31 |
+
|
32 |
+
<a href="large_1.jpg" class="fancybox" rel="gallery" title="Sample title 1"><img src="small_1.jpg" /></a>
|
33 |
+
<a href="large_2.jpg" class="fancybox" rel="gallery" title="Sample title 1"><img src="small_2.jpg" /></a>
|
34 |
+
|
35 |
+
Initialise the script like this:
|
36 |
+
|
37 |
+
<script>
|
38 |
+
$(document).ready(function() {
|
39 |
+
$('.fancybox').fancybox();
|
40 |
+
});
|
41 |
+
</script>
|
42 |
+
|
43 |
+
May also be passed an optional options object which will extend the default values. Example:
|
44 |
+
|
45 |
+
<script>
|
46 |
+
$(document).ready(function() {
|
47 |
+
$('.fancybox').fancybox({
|
48 |
+
padding : 5,
|
49 |
+
loop : false
|
50 |
+
});
|
51 |
+
});
|
52 |
+
</script>
|
53 |
+
|
54 |
+
Script uses the `href` attribute of the matched elements to obtain the location of the content and to figure out content type you want to display.
|
55 |
+
You can specify type directly by adding classname (fancybox.image, fancybox.iframe, etc).
|
56 |
+
|
57 |
+
//Ajax:
|
58 |
+
<a href="/example.html" class="fancybox fancybox.ajax">Example</a>
|
59 |
+
|
60 |
+
//Iframe:
|
61 |
+
<a href="example.html" class="fancybox fancybox.iframe">Example</a>
|
62 |
+
|
63 |
+
//Inline:
|
64 |
+
<a href="#example" class="fancybox">Example</a>
|
65 |
+
|
66 |
+
//SWF:
|
67 |
+
<a href="example.swf" class="fancybox">Example</a>
|
68 |
+
|
69 |
+
//Image:
|
70 |
+
<a href="example.jpg" class="fancybox">Example</a>
|
71 |
+
|
72 |
+
Note, ajax requests are subject to the [same origin policy](http://en.wikipedia.org/wiki/Same_origin_policy).
|
73 |
+
If fancyBox will not be able to get content type, error message will be displayed (this is different from previsous versions where 'ajax' was used as default type).
|
74 |
+
|
75 |
+
Advanced
|
76 |
+
--------
|
77 |
+
|
78 |
+
### Helpers
|
79 |
+
|
80 |
+
Helpers provide a simple mechanism to extend the capabilities of fancyBox. There are two built-in helpers - 'overlay' and 'title'.
|
81 |
+
You can disable them, set custom options or enable other helpers. Examples:
|
82 |
+
|
83 |
+
//Disable title helper
|
84 |
+
$(".fancybox").fancybox({
|
85 |
+
helpers: {
|
86 |
+
title: null
|
87 |
+
}
|
88 |
+
});
|
89 |
+
|
90 |
+
//Disable overlay helper
|
91 |
+
$(".fancybox").fancybox({
|
92 |
+
helpers: {
|
93 |
+
overlay : null
|
94 |
+
}
|
95 |
+
});
|
96 |
+
|
97 |
+
//Change title position and overlay color
|
98 |
+
$(".fancybox").fancybox({
|
99 |
+
helpers: {
|
100 |
+
title : {
|
101 |
+
type : 'inside'
|
102 |
+
},
|
103 |
+
overlay : {
|
104 |
+
css : {
|
105 |
+
'background-color' : '#fff'
|
106 |
+
}
|
107 |
+
}
|
108 |
+
}
|
109 |
+
});
|
110 |
+
|
111 |
+
//Enable thumbnail helper and set custom options
|
112 |
+
$(".fancybox").fancybox({
|
113 |
+
helpers: {
|
114 |
+
thumbs : {
|
115 |
+
width: 50,
|
116 |
+
height: 50
|
117 |
+
}
|
118 |
+
}
|
119 |
+
});
|
120 |
+
|
121 |
+
|
122 |
+
### API
|
123 |
+
|
124 |
+
Also available are event driven callback methods. The `this` keyword refers to the current or upcoming object (depends on callback method). Here is how you can change title:
|
125 |
+
|
126 |
+
$(".fancybox").fancybox({
|
127 |
+
beforeLoad : function() {
|
128 |
+
this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
|
129 |
+
|
130 |
+
/*
|
131 |
+
"this.element" refers to current element, so you can, for example, use the "alt" attribute of the image to store the title:
|
132 |
+
this.title = $(this.element).find('img').attr('alt');
|
133 |
+
*/
|
134 |
+
}
|
135 |
+
});
|
136 |
+
|
137 |
+
It`s possible to open fancyBox programmatically in various ways:
|
138 |
+
|
139 |
+
//HTML content:
|
140 |
+
$.fancybox( '<div><h1>Lorem Lipsum</h1><p>Lorem lipsum</p></div>', {
|
141 |
+
title : 'Custom Title'
|
142 |
+
});
|
143 |
+
|
144 |
+
//DOM element:
|
145 |
+
$.fancybox( $("#inline"), {
|
146 |
+
title : 'Custom Title'
|
147 |
+
});
|
148 |
+
|
149 |
+
//Custom object:
|
150 |
+
$.fancybox({
|
151 |
+
href: 'example.jpg',
|
152 |
+
title : 'Custom Title'
|
153 |
+
});
|
154 |
+
|
155 |
+
//Array of objects:
|
156 |
+
$.fancybox([
|
157 |
+
{
|
158 |
+
href: 'example1.jpg',
|
159 |
+
title : 'Custom Title 1'
|
160 |
+
},
|
161 |
+
{
|
162 |
+
href: 'example2.jpg',
|
163 |
+
title : 'Custom Title 2'
|
164 |
+
}
|
165 |
+
], {
|
166 |
+
padding: 0
|
167 |
+
});
|
168 |
+
|
169 |
+
There are several methods that allow you to interact with and manipulate fancyBox, example:
|
170 |
+
|
171 |
+
//Close fancybox:
|
172 |
+
$.fancybox.close();
|
173 |
+
|
174 |
+
There is a simply way to access wrapping elements using JS:
|
175 |
+
|
176 |
+
$.fancybox.wrap
|
177 |
+
$.fancybox.outer
|
178 |
+
$.fancybox.inner
|
179 |
+
|
180 |
+
You can override CSS to customize the look. For example, make navigation arrows always visible
|
181 |
+
and move them outside of area (use this snippet after including fancybox.css):
|
182 |
+
|
183 |
+
.fancybox-nav span {
|
184 |
+
visibility: visible;
|
185 |
+
}
|
186 |
+
|
187 |
+
.fancybox-prev {
|
188 |
+
left: -50px;
|
189 |
+
}
|
190 |
+
|
191 |
+
.fancybox-next {
|
192 |
+
right: 50px;
|
193 |
+
}
|
194 |
+
|
195 |
+
|
196 |
+
Bug tracker
|
197 |
+
-----------
|
198 |
+
|
199 |
+
Have a bug? Please create an issue on GitHub at https://github.com/fancyapps/fancyBox/issues
|
assets/fancyBox/demo/1_b.jpg
ADDED
Binary file
|
assets/fancyBox/demo/1_s.jpg
ADDED
Binary file
|
assets/fancyBox/demo/2_b.jpg
ADDED
Binary file
|
assets/fancyBox/demo/2_s.jpg
ADDED
Binary file
|
assets/fancyBox/demo/3_b.jpg
ADDED
Binary file
|
assets/fancyBox/demo/3_s.jpg
ADDED
Binary file
|
assets/fancyBox/demo/4_b.jpg
ADDED
Binary file
|
assets/fancyBox/demo/4_s.jpg
ADDED
Binary file
|
assets/fancyBox/demo/5_b.jpg
ADDED
Binary file
|
assets/fancyBox/demo/5_s.jpg
ADDED
Binary file
|
assets/fancyBox/demo/ajax.txt
ADDED
@@ -0,0 +1,15 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<div style="max-width:700px;">
|
2 |
+
<h2>Lorem ipsum dolor sit amet3</h2>
|
3 |
+
<p>
|
4 |
+
<a href="javascript:jQuery.fancybox.close();">Close me</a>
|
5 |
+
</p>
|
6 |
+
<p>
|
7 |
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas fermentum ante et sapien dignissim in viverra magna feugiat. Donec tempus ipsum nec neque dignissim quis eleifend eros gravida. Praesent nisi massa, sodales quis tincidunt ac, semper quis risus. In suscipit nisl sed leo aliquet consequat. Integer vitae augue in risus porttitor pellentesque eu eget odio. Fusce ut sagittis quam. Morbi aliquam interdum blandit. Integer pharetra tempor velit, aliquam dictum justo tempus sed. Morbi congue fringilla justo a feugiat. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent quis metus et nisl consectetur pharetra. Nam bibendum turpis eu metus luctus eu volutpat sem molestie. Nam sollicitudin porttitor lorem, ac ultricies est venenatis eu. Ut dignissim elit et orci feugiat ac placerat purus euismod. Ut mi lorem, cursus et sagittis elementum, luctus ac massa.
|
8 |
+
</p>
|
9 |
+
<p>
|
10 |
+
Phasellus et ligula vel diam ullamcorper volutpat. Integer rhoncus rhoncus aliquam. Aliquam erat volutpat. Aenean luctus vestibulum placerat. Quisque quam neque, lacinia aliquet eleifend ac, aliquet blandit felis. Curabitur porta ultricies dui, sit amet mattis quam euismod a. Ut eleifend scelerisque neque, sit amet accumsan odio consequat ut. Proin facilisis auctor elit sed accumsan. Cras dapibus nisl in nisi rhoncus laoreet. Nullam pellentesque tortor libero, eget facilisis ipsum. Donec ultricies tellus tellus, in tincidunt purus. Nullam in est aliquam velit scelerisque blandit. In tincidunt, magna a dapibus imperdiet, quam urna elementum leo, vitae rhoncus nisl velit cursus velit. In dignissim sem ac mauris rhoncus ornare.
|
11 |
+
</p>
|
12 |
+
<p>
|
13 |
+
Duis imperdiet velit vel quam malesuada suscipit imperdiet tellus hendrerit. Mauris vestibulum odio mauris, ut placerat leo. Mauris quis neque at tellus feugiat congue id non enim. Nam vehicula posuere nulla eget vehicula. Donec pretium purus nec ligula porta eu laoreet sapien venenatis. Nulla facilisi. Phasellus eget mi enim. Phasellus molestie tincidunt ultrices. Aenean id sem a tellus lobortis tincidunt. Nam laoreet nulla vel velit tincidunt ac rutrum libero malesuada. Nulla consequat dolor quis nisl tempor fermentum. Integer sodales pretium varius. Aenean a leo vitae odio dictum dignissim malesuada nec dolor. Phasellus adipiscing viverra est, ac sagittis libero sagittis quis. Sed interdum dapibus nunc et fringilla. Nunc vel velit et urna laoreet bibendum.
|
14 |
+
</p>
|
15 |
+
</div>
|
assets/fancyBox/demo/iframe.html
ADDED
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<title>fancyBox - iframe demo</title>
|
5 |
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
6 |
+
</head>
|
7 |
+
<body>
|
8 |
+
<h1>fancyBox - iframe demo</h1>
|
9 |
+
|
10 |
+
<p>
|
11 |
+
<a href="javascript:parent.jQuery.fancybox.close();">Close iframe parent</a>
|
12 |
+
</p>
|
13 |
+
|
14 |
+
<p>
|
15 |
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam scelerisque justo ac eros consectetur bibendum. In hac habitasse platea dictumst. Nulla aliquam turpis et tellus elementum luctus. Duis sit amet rhoncus velit. Duis nisl ligula, mattis interdum blandit laoreet, mattis id ante. Cras pulvinar lacus vitae nisi egestas non euismod neque bibendum. Vestibulum faucibus libero id ante molestie ultricies. Vestibulum quis nibh felis. Vestibulum libero nisl, vehicula vel ullamcorper sit amet, tristique sit amet augue. Etiam urna neque, porttitor sed sodales lacinia, posuere a nisl. Vestibulum blandit neque in sapien volutpat ac condimentum sapien auctor. Ut imperdiet venenatis ultricies. Phasellus accumsan, sem eu placerat commodo, felis purus commodo ipsum, sit amet vulputate orci est viverra est.
|
16 |
+
</p>
|
17 |
+
|
18 |
+
<p>
|
19 |
+
Aenean velit est, condimentum ut iaculis ut, accumsan at mi. Maecenas velit mi, venenatis ut condimentum at, ultrices vel tortor. Curabitur pharetra ornare dapibus. Ut volutpat cursus semper. In hac habitasse platea dictumst. Donec eu iaculis ipsum. Morbi eu dolor velit, a semper nunc.
|
20 |
+
</p>
|
21 |
+
</body>
|
22 |
+
</html>
|
assets/fancyBox/demo/index.html
ADDED
@@ -0,0 +1,302 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<title>fancyBox - Fancy jQuery Lightbox Alternative | Demonstration</title>
|
5 |
+
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
6 |
+
|
7 |
+
<!-- Add jQuery library -->
|
8 |
+
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
|
9 |
+
|
10 |
+
<!-- Add mousewheel plugin (this is optional) -->
|
11 |
+
<script type="text/javascript" src="../lib/jquery.mousewheel-3.0.6.pack.js"></script>
|
12 |
+
|
13 |
+
<!-- Add fancyBox main JS and CSS files -->
|
14 |
+
<script type="text/javascript" src="../source/jquery.fancybox.js"></script>
|
15 |
+
<link rel="stylesheet" type="text/css" href="../source/jquery.fancybox.css" media="screen" />
|
16 |
+
|
17 |
+
<!-- Add Button helper (this is optional) -->
|
18 |
+
<link rel="stylesheet" type="text/css" href="../source/helpers/jquery.fancybox-buttons.css?v=1.0.2" />
|
19 |
+
<script type="text/javascript" src="../source/helpers/jquery.fancybox-buttons.js?v=1.0.2"></script>
|
20 |
+
|
21 |
+
<!-- Add Thumbnail helper (this is optional) -->
|
22 |
+
<link rel="stylesheet" type="text/css" href="../source/helpers/jquery.fancybox-thumbs.css?v=1.0.2" />
|
23 |
+
<script type="text/javascript" src="../source/helpers/jquery.fancybox-thumbs.js?v=1.0.2"></script>
|
24 |
+
|
25 |
+
<!-- Add Media helper (this is optional) -->
|
26 |
+
<script type="text/javascript" src="../source/helpers/jquery.fancybox-media.js?v=1.0.0"></script>
|
27 |
+
|
28 |
+
<script type="text/javascript">
|
29 |
+
$(document).ready(function() {
|
30 |
+
/*
|
31 |
+
* Simple image gallery. Uses default settings
|
32 |
+
*/
|
33 |
+
|
34 |
+
$('.fancybox').fancybox();
|
35 |
+
|
36 |
+
/*
|
37 |
+
* Different effects
|
38 |
+
*/
|
39 |
+
|
40 |
+
// Change title type, overlay opening speed and opacity
|
41 |
+
$(".fancybox-effects-a").fancybox({
|
42 |
+
helpers: {
|
43 |
+
title : {
|
44 |
+
type : 'outside'
|
45 |
+
},
|
46 |
+
overlay : {
|
47 |
+
speedIn : 500,
|
48 |
+
opacity : 0.95
|
49 |
+
}
|
50 |
+
}
|
51 |
+
});
|
52 |
+
|
53 |
+
// Disable opening and closing animations, change title type
|
54 |
+
$(".fancybox-effects-b").fancybox({
|
55 |
+
openEffect : 'none',
|
56 |
+
closeEffect : 'none',
|
57 |
+
|
58 |
+
helpers : {
|
59 |
+
title : {
|
60 |
+
type : 'over'
|
61 |
+
}
|
62 |
+
}
|
63 |
+
});
|
64 |
+
|
65 |
+
// Set custom style, close if clicked, change title type and overlay color
|
66 |
+
$(".fancybox-effects-c").fancybox({
|
67 |
+
wrapCSS : 'fancybox-custom',
|
68 |
+
closeClick : true,
|
69 |
+
|
70 |
+
helpers : {
|
71 |
+
title : {
|
72 |
+
type : 'inside'
|
73 |
+
},
|
74 |
+
overlay : {
|
75 |
+
css : {
|
76 |
+
'background-color' : '#eee'
|
77 |
+
}
|
78 |
+
}
|
79 |
+
}
|
80 |
+
});
|
81 |
+
|
82 |
+
// Remove padding, set opening and closing animations, close if clicked and disable overlay
|
83 |
+
$(".fancybox-effects-d").fancybox({
|
84 |
+
padding: 0,
|
85 |
+
|
86 |
+
openEffect : 'elastic',
|
87 |
+
openSpeed : 150,
|
88 |
+
|
89 |
+
closeEffect : 'elastic',
|
90 |
+
closeSpeed : 150,
|
91 |
+
|
92 |
+
closeClick : true,
|
93 |
+
|
94 |
+
helpers : {
|
95 |
+
overlay : null
|
96 |
+
}
|
97 |
+
});
|
98 |
+
|
99 |
+
/*
|
100 |
+
* Button helper. Disable animations, hide close button, change title type and content
|
101 |
+
*/
|
102 |
+
|
103 |
+
$('.fancybox-buttons').fancybox({
|
104 |
+
openEffect : 'none',
|
105 |
+
closeEffect : 'none',
|
106 |
+
|
107 |
+
prevEffect : 'none',
|
108 |
+
nextEffect : 'none',
|
109 |
+
|
110 |
+
closeBtn : false,
|
111 |
+
|
112 |
+
helpers : {
|
113 |
+
title : {
|
114 |
+
type : 'inside'
|
115 |
+
},
|
116 |
+
buttons : {}
|
117 |
+
},
|
118 |
+
|
119 |
+
afterLoad : function() {
|
120 |
+
this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
|
121 |
+
}
|
122 |
+
});
|
123 |
+
|
124 |
+
|
125 |
+
/*
|
126 |
+
* Thumbnail helper. Disable animations, hide close button, arrows and slide to next gallery item if clicked
|
127 |
+
*/
|
128 |
+
|
129 |
+
$('.fancybox-thumbs').fancybox({
|
130 |
+
prevEffect : 'none',
|
131 |
+
nextEffect : 'none',
|
132 |
+
|
133 |
+
closeBtn : false,
|
134 |
+
arrows : false,
|
135 |
+
nextClick : true,
|
136 |
+
|
137 |
+
helpers : {
|
138 |
+
thumbs : {
|
139 |
+
width : 50,
|
140 |
+
height : 50
|
141 |
+
}
|
142 |
+
}
|
143 |
+
});
|
144 |
+
|
145 |
+
/*
|
146 |
+
* Media helper. Group items, disable animations, hide arrows, enable media and button helpers.
|
147 |
+
*/
|
148 |
+
$('.fancybox-media')
|
149 |
+
.attr('rel', 'media-gallery')
|
150 |
+
.fancybox({
|
151 |
+
openEffect : 'none',
|
152 |
+
closeEffect : 'none',
|
153 |
+
prevEffect : 'none',
|
154 |
+
nextEffect : 'none',
|
155 |
+
|
156 |
+
arrows : false,
|
157 |
+
helpers : {
|
158 |
+
media : {},
|
159 |
+
buttons : {}
|
160 |
+
}
|
161 |
+
});
|
162 |
+
|
163 |
+
/*
|
164 |
+
* Open manually
|
165 |
+
*/
|
166 |
+
|
167 |
+
$("#fancybox-manual-a").click(function() {
|
168 |
+
$.fancybox.open('1_b.jpg');
|
169 |
+
});
|
170 |
+
|
171 |
+
$("#fancybox-manual-b").click(function() {
|
172 |
+
$.fancybox.open({
|
173 |
+
href : 'iframe.html',
|
174 |
+
type : 'iframe',
|
175 |
+
padding : 5
|
176 |
+
});
|
177 |
+
});
|
178 |
+
|
179 |
+
$("#fancybox-manual-c").click(function() {
|
180 |
+
$.fancybox.open([
|
181 |
+
{
|
182 |
+
href : '1_b.jpg',
|
183 |
+
title : 'My title'
|
184 |
+
}, {
|
185 |
+
href : '2_b.jpg',
|
186 |
+
title : '2nd title'
|
187 |
+
}, {
|
188 |
+
href : '3_b.jpg'
|
189 |
+
}
|
190 |
+
], {
|
191 |
+
helpers : {
|
192 |
+
thumbs : {
|
193 |
+
width: 75,
|
194 |
+
height: 50
|
195 |
+
}
|
196 |
+
}
|
197 |
+
});
|
198 |
+
});
|
199 |
+
|
200 |
+
|
201 |
+
});
|
202 |
+
</script>
|
203 |
+
<style type="text/css">
|
204 |
+
.fancybox-custom .fancybox-outer {
|
205 |
+
box-shadow: 0 0 50px #222;
|
206 |
+
}
|
207 |
+
</style>
|
208 |
+
</head>
|
209 |
+
<body>
|
210 |
+
<h1>fancyBox</h1>
|
211 |
+
|
212 |
+
<p>This is a demonstration. More information and examples: <a href="http://fancyapps.com/fancybox/">www.fancyapps.com/fancybox/</a></p>
|
213 |
+
|
214 |
+
<h3>Simple image gallery</h3>
|
215 |
+
<p>
|
216 |
+
<a class="fancybox" href="1_b.jpg" data-fancybox-group="gallery" title="Lorem ipsum dolor sit amet"><img src="1_s.jpg" alt="" /></a>
|
217 |
+
|
218 |
+
<a class="fancybox" href="2_b.jpg" data-fancybox-group="gallery" title="Etiam quis mi eu elit temp"><img src="2_s.jpg" alt="" /></a>
|
219 |
+
|
220 |
+
<a class="fancybox" href="3_b.jpg" data-fancybox-group="gallery" title="Cras neque mi, semper leon"><img src="3_s.jpg" alt="" /></a>
|
221 |
+
|
222 |
+
<a class="fancybox" href="4_b.jpg" data-fancybox-group="gallery" title="Sed vel sapien vel sem uno"><img src="4_s.jpg" alt="" /></a>
|
223 |
+
</p>
|
224 |
+
|
225 |
+
<h3>Different effects</h3>
|
226 |
+
<p>
|
227 |
+
<a class="fancybox-effects-a" href="5_b.jpg" title="Lorem ipsum dolor sit amet, consectetur adipiscing elit"><img src="5_s.jpg" alt="" /></a>
|
228 |
+
|
229 |
+
<a class="fancybox-effects-b" href="5_b.jpg" title="Lorem ipsum dolor sit amet, consectetur adipiscing elit"><img src="5_s.jpg" alt="" /></a>
|
230 |
+
|
231 |
+
<a class="fancybox-effects-c" href="5_b.jpg" title="Lorem ipsum dolor sit amet, consectetur adipiscing elit"><img src="5_s.jpg" alt="" /></a>
|
232 |
+
|
233 |
+
<a class="fancybox-effects-d" href="5_b.jpg" title="Lorem ipsum dolor sit amet, consectetur adipiscing elit"><img src="5_s.jpg" alt="" /></a>
|
234 |
+
</p>
|
235 |
+
|
236 |
+
<h3>Various types</h3>
|
237 |
+
<p>
|
238 |
+
fancyBox will try to guess content type from href attribute but you can specify it directly by adding classname (fancybox.image, fancybox.iframe, etc).
|
239 |
+
</p>
|
240 |
+
<ul>
|
241 |
+
<li><a class="fancybox" href="#inline1" title="Lorem ipsum dolor sit amet">Inline</a></li>
|
242 |
+
<li><a class="fancybox fancybox.ajax" href="ajax.txt">Ajax</a></li>
|
243 |
+
<li><a class="fancybox fancybox.iframe" href="iframe.html">Iframe</a></li>
|
244 |
+
<li><a class="fancybox" href="http://www.adobe.com/jp/events/cs3_web_edition_tour/swfs/perform.swf">Swf</a></li>
|
245 |
+
</ul>
|
246 |
+
|
247 |
+
<div id="inline1" style="width:400px;display: none;">
|
248 |
+
<h3>Etiam quis mi eu elit</h3>
|
249 |
+
<p>
|
250 |
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam quis mi eu elit tempor facilisis id et neque. Nulla sit amet sem sapien. Vestibulum imperdiet porta ante ac ornare. Nulla et lorem eu nibh adipiscing ultricies nec at lacus. Cras laoreet ultricies sem, at blandit mi eleifend aliquam. Nunc enim ipsum, vehicula non pretium varius, cursus ac tortor. Vivamus fringilla congue laoreet. Quisque ultrices sodales orci, quis rhoncus justo auctor in. Phasellus dui eros, bibendum eu feugiat ornare, faucibus eu mi. Nunc aliquet tempus sem, id aliquam diam varius ac. Maecenas nisl nunc, molestie vitae eleifend vel, iaculis sed magna. Aenean tempus lacus vitae orci posuere porttitor eget non felis. Donec lectus elit, aliquam nec eleifend sit amet, vestibulum sed nunc.
|
251 |
+
</p>
|
252 |
+
</div>
|
253 |
+
|
254 |
+
<p>
|
255 |
+
Ajax example will not run from your local computer and requires a server to run.
|
256 |
+
</p>
|
257 |
+
|
258 |
+
<h3>Button helper</h3>
|
259 |
+
<p>
|
260 |
+
<a class="fancybox-buttons" data-fancybox-group="button" href="1_b.jpg"><img src="1_s.jpg" alt="" /></a>
|
261 |
+
|
262 |
+
<a class="fancybox-buttons" data-fancybox-group="button" href="2_b.jpg"><img src="2_s.jpg" alt="" /></a>
|
263 |
+
|
264 |
+
<a class="fancybox-buttons" data-fancybox-group="button" href="3_b.jpg"><img src="3_s.jpg" alt="" /></a>
|
265 |
+
|
266 |
+
<a class="fancybox-buttons" data-fancybox-group="button" href="4_b.jpg"><img src="4_s.jpg" alt="" /></a>
|
267 |
+
</p>
|
268 |
+
|
269 |
+
<h3>Thumbnail helper</h3>
|
270 |
+
<p>
|
271 |
+
<a class="fancybox-thumbs" data-fancybox-group="thumb" href="4_b.jpg"><img src="4_s.jpg" alt="" /></a>
|
272 |
+
|
273 |
+
<a class="fancybox-thumbs" data-fancybox-group="thumb" href="3_b.jpg"><img src="3_s.jpg" alt="" /></a>
|
274 |
+
|
275 |
+
<a class="fancybox-thumbs" data-fancybox-group="thumb" href="2_b.jpg"><img src="2_s.jpg" alt="" /></a>
|
276 |
+
|
277 |
+
<a class="fancybox-thumbs" data-fancybox-group="thumb" href="1_b.jpg"><img src="1_s.jpg" alt="" /></a>
|
278 |
+
</p>
|
279 |
+
|
280 |
+
<h3>Media helper</h3>
|
281 |
+
<ul>
|
282 |
+
<li><a class="fancybox-media" href="http://www.youtube.com/watch?v=opj24KnzrWo">Youtube</a></li>
|
283 |
+
<li><a class="fancybox-media" href="http://vimeo.com/25634903">Vimeo</a></li>
|
284 |
+
<li><a class="fancybox-media" href="http://www.metacafe.com/watch/7635964/">Metacafe</a></li>
|
285 |
+
<li><a class="fancybox-media" href="http://www.dailymotion.com/video/xoeylt_electric-guest-this-head-i-hold_music">Dailymotion</a></li>
|
286 |
+
<li><a class="fancybox-media" href="http://twitvid.com/QY7MD">Twitvid</a></li>
|
287 |
+
<li><a class="fancybox-media" href="http://twitpic.com/7p93st">Twitpic</a></li>
|
288 |
+
<li><a class="fancybox-media" href="http://instagr.am/p/IejkuUGxQn">Instagram</a></li>
|
289 |
+
</ul>
|
290 |
+
|
291 |
+
<h3>Open manually</h3>
|
292 |
+
<ul>
|
293 |
+
<li><a id="fancybox-manual-a" href="javascript:;">Open single item</a></li>
|
294 |
+
<li><a id="fancybox-manual-b" href="javascript:;">Open single item, custom options</a></li>
|
295 |
+
<li><a id="fancybox-manual-c" href="javascript:;">Open gallery</a></li>
|
296 |
+
</ul>
|
297 |
+
|
298 |
+
<p>
|
299 |
+
Photo Credit: Instagrammer @whitjohns
|
300 |
+
</p>
|
301 |
+
</body>
|
302 |
+
</html>
|
assets/fancyBox/lib/jquery-1.7.2.min.js
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
1 |
+
/*! jQuery v1.7.2 jquery.com | jquery.org/license */
|
2 |
+
(function(a,b){function cy(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cu(a){if(!cj[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ck||(ck=c.createElement("iframe"),ck.frameBorder=ck.width=ck.height=0),b.appendChild(ck);if(!cl||!ck.createElement)cl=(ck.contentWindow||ck.contentDocument).document,cl.write((f.support.boxModel?"<!doctype html>":"")+"<html><body>"),cl.close();d=cl.createElement(a),cl.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ck)}cj[a]=e}return cj[a]}function ct(a,b){var c={};f.each(cp.concat.apply([],cp.slice(0,b)),function(){c[this]=a});return c}function cs(){cq=b}function cr(){setTimeout(cs,0);return cq=f.now()}function ci(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ch(){try{return new a.XMLHttpRequest}catch(b){}}function cb(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function ca(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function b_(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bD.test(a)?d(a,e):b_(a+"["+(typeof e=="object"?b:"")+"]",e,c,d)});else if(!c&&f.type(b)==="object")for(var e in b)b_(a+"["+e+"]",b[e],c,d);else d(a,b)}function b$(a,c){var d,e,g=f.ajaxSettings.flatOptions||{};for(d in c)c[d]!==b&&((g[d]?a:e||(e={}))[d]=c[d]);e&&f.extend(!0,a,e)}function bZ(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bS,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bZ(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bZ(a,c,d,e,"*",g));return l}function bY(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bO),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bB(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?1:0,g=4;if(d>0){if(c!=="border")for(;e<g;e+=2)c||(d-=parseFloat(f.css(a,"padding"+bx[e]))||0),c==="margin"?d+=parseFloat(f.css(a,c+bx[e]))||0:d-=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0;return d+"px"}d=by(a,b);if(d<0||d==null)d=a.style[b];if(bt.test(d))return d;d=parseFloat(d)||0;if(c)for(;e<g;e+=2)d+=parseFloat(f.css(a,"padding"+bx[e]))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+bx[e]+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+bx[e]))||0);return d+"px"}function bo(a){var b=c.createElement("div");bh.appendChild(b),b.innerHTML=a.outerHTML;return b.firstChild}function bn(a){var b=(a.nodeName||"").toLowerCase();b==="input"?bm(a):b!=="script"&&typeof a.getElementsByTagName!="undefined"&&f.grep(a.getElementsByTagName("input"),bm)}function bm(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bl(a){return typeof a.getElementsByTagName!="undefined"?a.getElementsByTagName("*"):typeof a.querySelectorAll!="undefined"?a.querySelectorAll("*"):[]}function bk(a,b){var c;b.nodeType===1&&(b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase(),c==="object"?b.outerHTML=a.outerHTML:c!=="input"||a.type!=="checkbox"&&a.type!=="radio"?c==="option"?b.selected=a.defaultSelected:c==="input"||c==="textarea"?b.defaultValue=a.defaultValue:c==="script"&&b.text!==a.text&&(b.text=a.text):(a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value)),b.removeAttribute(f.expando),b.removeAttribute("_submit_attached"),b.removeAttribute("_change_attached"))}function bj(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c,d,e,g=f._data(a),h=f._data(b,g),i=g.events;if(i){delete h.handle,h.events={};for(c in i)for(d=0,e=i[c].length;d<e;d++)f.event.add(b,c,i[c][d])}h.data&&(h.data=f.extend({},h.data))}}function bi(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function U(a){var b=V.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}function T(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(O.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function S(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function K(){return!0}function J(){return!1}function n(a,b,c){var d=b+"defer",e=b+"queue",g=b+"mark",h=f._data(a,d);h&&(c==="queue"||!f._data(a,e))&&(c==="mark"||!f._data(a,g))&&setTimeout(function(){!f._data(a,e)&&!f._data(a,g)&&(f.removeData(a,d,!0),h.fire())},0)}function m(a){for(var b in a){if(b==="data"&&f.isEmptyObject(a[b]))continue;if(b!=="toJSON")return!1}return!0}function l(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(k,"-$1").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNumeric(d)?+d:j.test(d)?f.parseJSON(d):d}catch(g){}f.data(a,c,d)}else d=b}return d}function h(a){var b=g[a]={},c,d;a=a.split(/\s+/);for(c=0,d=a.length;c<d;c++)b[a[c]]=!0;return b}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,n=/^[\],:{}\s]*$/,o=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,p=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,q=/(?:^|:|,)(?:\s*\[)+/g,r=/(webkit)[ \/]([\w.]+)/,s=/(opera)(?:.*version)?[ \/]([\w.]+)/,t=/(msie) ([\w.]+)/,u=/(mozilla)(?:.*? rv:([\w.]+))?/,v=/-([a-z]|[0-9])/ig,w=/^-ms-/,x=function(a,b){return(b+"").toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=m.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.7.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.add(a);return this},eq:function(a){a=+a;return a===-1?this.slice(a):this.slice(a,a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.fireWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").off("ready")}},bindReady:function(){if(!A){A=e.Callbacks("once memory");if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a!=null&&a==a.window},isNumeric:function(a){return!isNaN(parseFloat(a))&&isFinite(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;try{if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}var d;for(d in a);return d===b||D.call(a,d)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw new Error(a)},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(n.test(b.replace(o,"@").replace(p,"]").replace(q,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(c){if(typeof c!="string"||!c)return null;var d,f;try{a.DOMParser?(f=new DOMParser,d=f.parseFromString(c,"text/xml")):(d=new ActiveXObject("Microsoft.XMLDOM"),d.async="false",d.loadXML(c))}catch(g){d=b}(!d||!d.documentElement||d.getElementsByTagName("parsererror").length)&&e.error("Invalid XML: "+c);return d},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,"ms-").replace(v,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b,c){var d;if(b){if(H)return H.call(b,a,c);d=b.length,c=c?c<0?Math.max(0,d+c):c:0;for(;c<d;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h,i){var j,k=d==null,l=0,m=a.length;if(d&&typeof d=="object"){for(l in d)e.access(a,c,l,d[l],1,h,f);g=1}else if(f!==b){j=i===b&&e.isFunction(f),k&&(j?(j=c,c=function(a,b,c){return j.call(e(a),c)}):(c.call(a,f),c=null));if(c)for(;l<m;l++)c(a[l],d,j?f.call(a[l],l,c(a[l],d)):f,i);g=1}return g?a:k?c.call(a):m?c(a[0],d):h},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=r.exec(a)||s.exec(a)||t.exec(a)||a.indexOf("compatible")<0&&u.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g={};f.Callbacks=function(a){a=a?g[a]||h(a):{};var c=[],d=[],e,i,j,k,l,m,n=function(b){var d,e,g,h,i;for(d=0,e=b.length;d<e;d++)g=b[d],h=f.type(g),h==="array"?n(g):h==="function"&&(!a.unique||!p.has(g))&&c.push(g)},o=function(b,f){f=f||[],e=!a.memory||[b,f],i=!0,j=!0,m=k||0,k=0,l=c.length;for(;c&&m<l;m++)if(c[m].apply(b,f)===!1&&a.stopOnFalse){e=!0;break}j=!1,c&&(a.once?e===!0?p.disable():c=[]:d&&d.length&&(e=d.shift(),p.fireWith(e[0],e[1])))},p={add:function(){if(c){var a=c.length;n(arguments),j?l=c.length:e&&e!==!0&&(k=a,o(e[0],e[1]))}return this},remove:function(){if(c){var b=arguments,d=0,e=b.length;for(;d<e;d++)for(var f=0;f<c.length;f++)if(b[d]===c[f]){j&&f<=l&&(l--,f<=m&&m--),c.splice(f--,1);if(a.unique)break}}return this},has:function(a){if(c){var b=0,d=c.length;for(;b<d;b++)if(a===c[b])return!0}return!1},empty:function(){c=[];return this},disable:function(){c=d=e=b;return this},disabled:function(){return!c},lock:function(){d=b,(!e||e===!0)&&p.disable();return this},locked:function(){return!d},fireWith:function(b,c){d&&(j?a.once||d.push([b,c]):(!a.once||!e)&&o(b,c));return this},fire:function(){p.fireWith(this,arguments);return this},fired:function(){return!!i}};return p};var i=[].slice;f.extend({Deferred:function(a){var b=f.Callbacks("once memory"),c=f.Callbacks("once memory"),d=f.Callbacks("memory"),e="pending",g={resolve:b,reject:c,notify:d},h={done:b.add,fail:c.add,progress:d.add,state:function(){return e},isResolved:b.fired,isRejected:c.fired,then:function(a,b,c){i.done(a).fail(b).progress(c);return this},always:function(){i.done.apply(i,arguments).fail.apply(i,arguments);return this},pipe:function(a,b,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[b,"reject"],progress:[c,"notify"]},function(a,b){var c=b[0],e=b[1],g;f.isFunction(c)?i[a](function(){g=c.apply(this,arguments),g&&f.isFunction(g.promise)?g.promise().then(d.resolve,d.reject,d.notify):d[e+"With"](this===i?d:this,[g])}):i[a](d[e])})}).promise()},promise:function(a){if(a==null)a=h;else for(var b in h)a[b]=h[b];return a}},i=h.promise({}),j;for(j in g)i[j]=g[j].fire,i[j+"With"]=g[j].fireWith;i.done(function(){e="resolved"},c.disable,d.lock).fail(function(){e="rejected"},b.disable,d.lock),a&&a.call(i,i);return i},when:function(a){function m(a){return function(b){e[a]=arguments.length>1?i.call(arguments,0):b,j.notifyWith(k,e)}}function l(a){return function(c){b[a]=arguments.length>1?i.call(arguments,0):c,--g||j.resolveWith(j,b)}}var b=i.call(arguments,0),c=0,d=b.length,e=Array(d),g=d,h=d,j=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred(),k=j.promise();if(d>1){for(;c<d;c++)b[c]&&b[c].promise&&f.isFunction(b[c].promise)?b[c].promise().then(l(c),j.reject,m(c)):--g;g||j.resolveWith(j,b)}else j!==a&&j.resolveWith(j,d?[a]:[]);return k}}),f.support=function(){var b,d,e,g,h,i,j,k,l,m,n,o,p=c.createElement("div"),q=c.documentElement;p.setAttribute("className","t"),p.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=p.getElementsByTagName("*"),e=p.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=p.getElementsByTagName("input")[0],b={leadingWhitespace:p.firstChild.nodeType===3,tbody:!p.getElementsByTagName("tbody").length,htmlSerialize:!!p.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:p.className!=="t",enctype:!!c.createElement("form").enctype,html5Clone:c.createElement("nav").cloneNode(!0).outerHTML!=="<:nav></:nav>",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,pixelMargin:!0},f.boxModel=b.boxModel=c.compatMode==="CSS1Compat",i.checked=!0,b.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,b.optDisabled=!h.disabled;try{delete p.test}catch(r){b.deleteExpando=!1}!p.addEventListener&&p.attachEvent&&p.fireEvent&&(p.attachEvent("onclick",function(){b.noCloneEvent=!1}),p.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),b.radioValue=i.value==="t",i.setAttribute("checked","checked"),i.setAttribute("name","t"),p.appendChild(i),j=c.createDocumentFragment(),j.appendChild(p.lastChild),b.checkClone=j.cloneNode(!0).cloneNode(!0).lastChild.checked,b.appendChecked=i.checked,j.removeChild(i),j.appendChild(p);if(p.attachEvent)for(n in{submit:1,change:1,focusin:1})m="on"+n,o=m in p,o||(p.setAttribute(m,"return;"),o=typeof p[m]=="function"),b[n+"Bubbles"]=o;j.removeChild(p),j=g=h=p=i=null,f(function(){var d,e,g,h,i,j,l,m,n,q,r,s,t,u=c.getElementsByTagName("body")[0];!u||(m=1,t="padding:0;margin:0;border:",r="position:absolute;top:0;left:0;width:1px;height:1px;",s=t+"0;visibility:hidden;",n="style='"+r+t+"5px solid #000;",q="<div "+n+"display:block;'><div style='"+t+"0;display:block;overflow:hidden;'></div></div>"+"<table "+n+"' cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",d=c.createElement("div"),d.style.cssText=s+"width:0;height:0;position:static;top:0;margin-top:"+m+"px",u.insertBefore(d,u.firstChild),p=c.createElement("div"),d.appendChild(p),p.innerHTML="<table><tr><td style='"+t+"0;display:none'></td><td>t</td></tr></table>",k=p.getElementsByTagName("td"),o=k[0].offsetHeight===0,k[0].style.display="",k[1].style.display="none",b.reliableHiddenOffsets=o&&k[0].offsetHeight===0,a.getComputedStyle&&(p.innerHTML="",l=c.createElement("div"),l.style.width="0",l.style.marginRight="0",p.style.width="2px",p.appendChild(l),b.reliableMarginRight=(parseInt((a.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)===0),typeof p.style.zoom!="undefined"&&(p.innerHTML="",p.style.width=p.style.padding="1px",p.style.border=0,p.style.overflow="hidden",p.style.display="inline",p.style.zoom=1,b.inlineBlockNeedsLayout=p.offsetWidth===3,p.style.display="block",p.style.overflow="visible",p.innerHTML="<div style='width:5px;'></div>",b.shrinkWrapBlocks=p.offsetWidth!==3),p.style.cssText=r+s,p.innerHTML=q,e=p.firstChild,g=e.firstChild,i=e.nextSibling.firstChild.firstChild,j={doesNotAddBorder:g.offsetTop!==5,doesAddBorderForTableAndCells:i.offsetTop===5},g.style.position="fixed",g.style.top="20px",j.fixedPosition=g.offsetTop===20||g.offsetTop===15,g.style.position=g.style.top="",e.style.overflow="hidden",e.style.position="relative",j.subtractsBorderForOverflowNotVisible=g.offsetTop===-5,j.doesNotIncludeMarginInBodyOffset=u.offsetTop!==m,a.getComputedStyle&&(p.style.marginTop="1%",b.pixelMargin=(a.getComputedStyle(p,null)||{marginTop:0}).marginTop!=="1%"),typeof d.style.zoom!="undefined"&&(d.style.zoom=1),u.removeChild(d),l=p=d=null,f.extend(b,j))});return b}();var j=/^(?:\{.*\}|\[.*\])$/,k=/([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!m(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g,h,i,j=f.expando,k=typeof c=="string",l=a.nodeType,m=l?f.cache:a,n=l?a[j]:a[j]&&j,o=c==="events";if((!n||!m[n]||!o&&!e&&!m[n].data)&&k&&d===b)return;n||(l?a[j]=n=++f.uuid:n=j),m[n]||(m[n]={},l||(m[n].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?m[n]=f.extend(m[n],c):m[n].data=f.extend(m[n].data,c);g=h=m[n],e||(h.data||(h.data={}),h=h.data),d!==b&&(h[f.camelCase(c)]=d);if(o&&!h[c])return g.events;k?(i=h[c],i==null&&(i=h[f.camelCase(c)])):i=h;return i}},removeData:function(a,b,c){if(!!f.acceptData(a)){var d,e,g,h=f.expando,i=a.nodeType,j=i?f.cache:a,k=i?a[h]:h;if(!j[k])return;if(b){d=c?j[k]:j[k].data;if(d){f.isArray(b)||(b in d?b=[b]:(b=f.camelCase(b),b in d?b=[b]:b=b.split(" ")));for(e=0,g=b.length;e<g;e++)delete d[b[e]];if(!(c?m:f.isEmptyObject)(d))return}}if(!c){delete j[k].data;if(!m(j[k]))return}f.support.deleteExpando||!j.setInterval?delete j[k]:j[k]=null,i&&(f.support.deleteExpando?delete a[h]:a.removeAttribute?a.removeAttribute(h):a[h]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d,e,g,h,i,j=this[0],k=0,m=null;if(a===b){if(this.length){m=f.data(j);if(j.nodeType===1&&!f._data(j,"parsedAttrs")){g=j.attributes;for(i=g.length;k<i;k++)h=g[k].name,h.indexOf("data-")===0&&(h=f.camelCase(h.substring(5)),l(j,h,m[h]));f._data(j,"parsedAttrs",!0)}}return m}if(typeof a=="object")return this.each(function(){f.data(this,a)});d=a.split(".",2),d[1]=d[1]?"."+d[1]:"",e=d[1]+"!";return f.access(this,function(c){if(c===b){m=this.triggerHandler("getData"+e,[d[0]]),m===b&&j&&(m=f.data(j,a),m=l(j,a,m));return m===b&&d[1]?this.data(d[0]):m}d[1]=c,this.each(function(){var b=f(this);b.triggerHandler("setData"+e,d),f.data(this,a,c),b.triggerHandler("changeData"+e,d)})},null,c,arguments.length>1,null,!1)},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,b){a&&(b=(b||"fx")+"mark",f._data(a,b,(f._data(a,b)||0)+1))},_unmark:function(a,b,c){a!==!0&&(c=b,b=a,a=!1);if(b){c=c||"fx";var d=c+"mark",e=a?0:(f._data(b,d)||1)-1;e?f._data(b,d,e):(f.removeData(b,d,!0),n(b,c,"mark"))}},queue:function(a,b,c){var d;if(a){b=(b||"fx")+"queue",d=f._data(a,b),c&&(!d||f.isArray(c)?d=f._data(a,b,f.makeArray(c)):d.push(c));return d||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e={};d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),f._data(a,b+".run",e),d.call(a,function(){f.dequeue(a,b)},e)),c.length||(f.removeData(a,b+"queue "+b+".run",!0),n(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){var d=2;typeof a!="string"&&(c=a,a="fx",d--);if(arguments.length<d)return f.queue(this[0],a);return c===b?this:this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f.Callbacks("once memory"),!0))h++,l.add(m);m();return d.promise(c)}});var o=/[\n\t\r]/g,p=/\s+/,q=/\r/g,r=/^(?:button|input)$/i,s=/^(?:button|input|object|select|textarea)$/i,t=/^a(?:rea)?$/i,u=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,v=f.support.getSetAttribute,w,x,y;f.fn.extend({attr:function(a,b){return f.access(this,f.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,f.prop,a,b,arguments.length>1)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(p);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(p);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(o," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(p);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ",c=0,d=this.length;for(;c<d;c++)if(this[c].nodeType===1&&(" "+this[c].className+" ").replace(o," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e,g=this[0];{if(!!arguments.length){e=f.isFunction(a);return this.each(function(d){var g=f(this),h;if(this.nodeType===1){e?h=a.call(this,d,g.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.type]||f.valHooks[this.nodeName.toLowerCase()];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}if(g){c=f.valHooks[g.type]||f.valHooks[g.nodeName.toLowerCase()];if(c&&"get"in c&&(d=c.get(g,"value"))!==b)return d;d=g.value;return typeof d=="string"?d.replace(q,""):d==null?"":d}}}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c,d,e,g=a.selectedIndex,h=[],i=a.options,j=a.type==="select-one";if(g<0)return null;c=j?g:0,d=j?g+1:i.length;for(;c<d;c++){e=i[c];if(e.selected&&(f.support.optDisabled?!e.disabled:e.getAttribute("disabled")===null)&&(!e.parentNode.disabled||!f.nodeName(e.parentNode,"optgroup"))){b=f(e).val();if(j)return b;h.push(b)}}if(j&&!h.length&&i.length)return f(i[g]).val();return h},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(a,c,d,e){var g,h,i,j=a.nodeType;if(!!a&&j!==3&&j!==8&&j!==2){if(e&&c in f.attrFn)return f(a)[c](d);if(typeof a.getAttribute=="undefined")return f.prop(a,c,d);i=j!==1||!f.isXMLDoc(a),i&&(c=c.toLowerCase(),h=f.attrHooks[c]||(u.test(c)?x:w));if(d!==b){if(d===null){f.removeAttr(a,c);return}if(h&&"set"in h&&i&&(g=h.set(a,d,c))!==b)return g;a.setAttribute(c,""+d);return d}if(h&&"get"in h&&i&&(g=h.get(a,c))!==null)return g;g=a.getAttribute(c);return g===null?b:g}},removeAttr:function(a,b){var c,d,e,g,h,i=0;if(b&&a.nodeType===1){d=b.toLowerCase().split(p),g=d.length;for(;i<g;i++)e=d[i],e&&(c=f.propFix[e]||e,h=u.test(e),h||f.attr(a,e,""),a.removeAttribute(v?e:c),h&&c in a&&(a[c]=!1))}},attrHooks:{type:{set:function(a,b){if(r.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},value:{get:function(a,b){if(w&&f.nodeName(a,"button"))return w.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(w&&f.nodeName(a,"button"))return w.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e,g,h,i=a.nodeType;if(!!a&&i!==3&&i!==8&&i!==2){h=i!==1||!f.isXMLDoc(a),h&&(c=f.propFix[c]||c,g=f.propHooks[c]);return d!==b?g&&"set"in g&&(e=g.set(a,d,c))!==b?e:a[c]=d:g&&"get"in g&&(e=g.get(a,c))!==null?e:a[c]}},propHooks:{tabIndex:{get:function(a){var c=a.getAttributeNode("tabindex");return c&&c.specified?parseInt(c.value,10):s.test(a.nodeName)||t.test(a.nodeName)&&a.href?0:b}}}}),f.attrHooks.tabindex=f.propHooks.tabIndex,x={get:function(a,c){var d,e=f.prop(a,c);return e===!0||typeof e!="boolean"&&(d=a.getAttributeNode(c))&&d.nodeValue!==!1?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},v||(y={name:!0,id:!0,coords:!0},w=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&(y[c]?d.nodeValue!=="":d.specified)?d.nodeValue:b},set:function(a,b,d){var e=a.getAttributeNode(d);e||(e=c.createAttribute(d),a.setAttributeNode(e));return e.nodeValue=b+""}},f.attrHooks.tabindex.set=w.set,f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})}),f.attrHooks.contenteditable={get:w.get,set:function(a,b,c){b===""&&(b="false"),w.set(a,b,c)}}),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex);return null}})),f.support.enctype||(f.propFix.enctype="encoding"),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var z=/^(?:textarea|input|select)$/i,A=/^([^\.]*)?(?:\.(.+))?$/,B=/(?:^|\s)hover(\.\S+)?\b/,C=/^key/,D=/^(?:mouse|contextmenu)|click/,E=/^(?:focusinfocus|focusoutblur)$/,F=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,G=function(
|
3 |
+
a){var b=F.exec(a);b&&(b[1]=(b[1]||"").toLowerCase(),b[3]=b[3]&&new RegExp("(?:^|\\s)"+b[3]+"(?:\\s|$)"));return b},H=function(a,b){var c=a.attributes||{};return(!b[1]||a.nodeName.toLowerCase()===b[1])&&(!b[2]||(c.id||{}).value===b[2])&&(!b[3]||b[3].test((c["class"]||{}).value))},I=function(a){return f.event.special.hover?a:a.replace(B,"mouseenter$1 mouseleave$1")};f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3||a.nodeType===8||!c||!d||!(h=f._data(a)))){d.handler&&(p=d,d=p.handler,g=p.selector),d.guid||(d.guid=f.guid++),j=h.events,j||(h.events=j={}),i=h.handle,i||(h.handle=i=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.dispatch.apply(i.elem,arguments):b},i.elem=a),c=f.trim(I(c)).split(" ");for(k=0;k<c.length;k++){l=A.exec(c[k])||[],m=l[1],n=(l[2]||"").split(".").sort(),s=f.event.special[m]||{},m=(g?s.delegateType:s.bindType)||m,s=f.event.special[m]||{},o=f.extend({type:m,origType:l[1],data:e,handler:d,guid:d.guid,selector:g,quick:g&&G(g),namespace:n.join(".")},p),r=j[m];if(!r){r=j[m]=[],r.delegateCount=0;if(!s.setup||s.setup.call(a,e,n,i)===!1)a.addEventListener?a.addEventListener(m,i,!1):a.attachEvent&&a.attachEvent("on"+m,i)}s.add&&(s.add.call(a,o),o.handler.guid||(o.handler.guid=d.guid)),g?r.splice(r.delegateCount++,0,o):r.push(o),f.event.global[m]=!0}a=null}},global:{},remove:function(a,b,c,d,e){var g=f.hasData(a)&&f._data(a),h,i,j,k,l,m,n,o,p,q,r,s;if(!!g&&!!(o=g.events)){b=f.trim(I(b||"")).split(" ");for(h=0;h<b.length;h++){i=A.exec(b[h])||[],j=k=i[1],l=i[2];if(!j){for(j in o)f.event.remove(a,j+b[h],c,d,!0);continue}p=f.event.special[j]||{},j=(d?p.delegateType:p.bindType)||j,r=o[j]||[],m=r.length,l=l?new RegExp("(^|\\.)"+l.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null;for(n=0;n<r.length;n++)s=r[n],(e||k===s.origType)&&(!c||c.guid===s.guid)&&(!l||l.test(s.namespace))&&(!d||d===s.selector||d==="**"&&s.selector)&&(r.splice(n--,1),s.selector&&r.delegateCount--,p.remove&&p.remove.call(a,s));r.length===0&&m!==r.length&&((!p.teardown||p.teardown.call(a,l)===!1)&&f.removeEvent(a,j,g.handle),delete o[j])}f.isEmptyObject(o)&&(q=g.handle,q&&(q.elem=null),f.removeData(a,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){if(!e||e.nodeType!==3&&e.nodeType!==8){var h=c.type||c,i=[],j,k,l,m,n,o,p,q,r,s;if(E.test(h+f.event.triggered))return;h.indexOf("!")>=0&&(h=h.slice(0,-1),k=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.shift(),i.sort());if((!e||f.event.customEvent[h])&&!f.event.global[h])return;c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.isTrigger=!0,c.exclusive=k,c.namespace=i.join("."),c.namespace_re=c.namespace?new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,o=h.indexOf(":")<0?"on"+h:"";if(!e){j=f.cache;for(l in j)j[l].events&&j[l].events[h]&&f.event.trigger(c,d,j[l].handle.elem,!0);return}c.result=b,c.target||(c.target=e),d=d!=null?f.makeArray(d):[],d.unshift(c),p=f.event.special[h]||{};if(p.trigger&&p.trigger.apply(e,d)===!1)return;r=[[e,p.bindType||h]];if(!g&&!p.noBubble&&!f.isWindow(e)){s=p.delegateType||h,m=E.test(s+h)?e:e.parentNode,n=null;for(;m;m=m.parentNode)r.push([m,s]),n=m;n&&n===e.ownerDocument&&r.push([n.defaultView||n.parentWindow||a,s])}for(l=0;l<r.length&&!c.isPropagationStopped();l++)m=r[l][0],c.type=r[l][1],q=(f._data(m,"events")||{})[c.type]&&f._data(m,"handle"),q&&q.apply(m,d),q=o&&m[o],q&&f.acceptData(m)&&q.apply(m,d)===!1&&c.preventDefault();c.type=h,!g&&!c.isDefaultPrevented()&&(!p._default||p._default.apply(e.ownerDocument,d)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)&&o&&e[h]&&(h!=="focus"&&h!=="blur"||c.target.offsetWidth!==0)&&!f.isWindow(e)&&(n=e[o],n&&(e[o]=null),f.event.triggered=h,e[h](),f.event.triggered=b,n&&(e[o]=n));return c.result}},dispatch:function(c){c=f.event.fix(c||a.event);var d=(f._data(this,"events")||{})[c.type]||[],e=d.delegateCount,g=[].slice.call(arguments,0),h=!c.exclusive&&!c.namespace,i=f.event.special[c.type]||{},j=[],k,l,m,n,o,p,q,r,s,t,u;g[0]=c,c.delegateTarget=this;if(!i.preDispatch||i.preDispatch.call(this,c)!==!1){if(e&&(!c.button||c.type!=="click")){n=f(this),n.context=this.ownerDocument||this;for(m=c.target;m!=this;m=m.parentNode||this)if(m.disabled!==!0){p={},r=[],n[0]=m;for(k=0;k<e;k++)s=d[k],t=s.selector,p[t]===b&&(p[t]=s.quick?H(m,s.quick):n.is(t)),p[t]&&r.push(s);r.length&&j.push({elem:m,matches:r})}}d.length>e&&j.push({elem:this,matches:d.slice(e)});for(k=0;k<j.length&&!c.isPropagationStopped();k++){q=j[k],c.currentTarget=q.elem;for(l=0;l<q.matches.length&&!c.isImmediatePropagationStopped();l++){s=q.matches[l];if(h||!c.namespace&&!s.namespace||c.namespace_re&&c.namespace_re.test(s.namespace))c.data=s.data,c.handleObj=s,o=((f.event.special[s.origType]||{}).handle||s.handler).apply(q.elem,g),o!==b&&(c.result=o,o===!1&&(c.preventDefault(),c.stopPropagation()))}}i.postDispatch&&i.postDispatch.call(this,c);return c.result}},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){a.which==null&&(a.which=b.charCode!=null?b.charCode:b.keyCode);return a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,d){var e,f,g,h=d.button,i=d.fromElement;a.pageX==null&&d.clientX!=null&&(e=a.target.ownerDocument||c,f=e.documentElement,g=e.body,a.pageX=d.clientX+(f&&f.scrollLeft||g&&g.scrollLeft||0)-(f&&f.clientLeft||g&&g.clientLeft||0),a.pageY=d.clientY+(f&&f.scrollTop||g&&g.scrollTop||0)-(f&&f.clientTop||g&&g.clientTop||0)),!a.relatedTarget&&i&&(a.relatedTarget=i===a.target?d.toElement:i),!a.which&&h!==b&&(a.which=h&1?1:h&2?3:h&4?2:0);return a}},fix:function(a){if(a[f.expando])return a;var d,e,g=a,h=f.event.fixHooks[a.type]||{},i=h.props?this.props.concat(h.props):this.props;a=f.Event(g);for(d=i.length;d;)e=i[--d],a[e]=g[e];a.target||(a.target=g.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),a.metaKey===b&&(a.metaKey=a.ctrlKey);return h.filter?h.filter(a,g):a},special:{ready:{setup:f.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}},simulate:function(a,b,c,d){var e=f.extend(new f.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?f.event.trigger(e,null,b):f.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},f.event.handle=f.event.dispatch,f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!(this instanceof f.Event))return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?K:J):this.type=a,b&&f.extend(this,b),this.timeStamp=a&&a.timeStamp||f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=K;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=K;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=K,this.stopPropagation()},isDefaultPrevented:J,isPropagationStopped:J,isImmediatePropagationStopped:J},f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c=this,d=a.relatedTarget,e=a.handleObj,g=e.selector,h;if(!d||d!==c&&!f.contains(c,d))a.type=e.origType,h=e.handler.apply(this,arguments),a.type=b;return h}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(){if(f.nodeName(this,"form"))return!1;f.event.add(this,"click._submit keypress._submit",function(a){var c=a.target,d=f.nodeName(c,"input")||f.nodeName(c,"button")?c.form:b;d&&!d._submit_attached&&(f.event.add(d,"submit._submit",function(a){a._submit_bubble=!0}),d._submit_attached=!0)})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&f.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){if(f.nodeName(this,"form"))return!1;f.event.remove(this,"._submit")}}),f.support.changeBubbles||(f.event.special.change={setup:function(){if(z.test(this.nodeName)){if(this.type==="checkbox"||this.type==="radio")f.event.add(this,"propertychange._change",function(a){a.originalEvent.propertyName==="checked"&&(this._just_changed=!0)}),f.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1,f.event.simulate("change",this,a,!0))});return!1}f.event.add(this,"beforeactivate._change",function(a){var b=a.target;z.test(b.nodeName)&&!b._change_attached&&(f.event.add(b,"change._change",function(a){this.parentNode&&!a.isSimulated&&!a.isTrigger&&f.event.simulate("change",this.parentNode,a,!0)}),b._change_attached=!0)})},handle:function(a){var b=a.target;if(this!==b||a.isSimulated||a.isTrigger||b.type!=="radio"&&b.type!=="checkbox")return a.handleObj.handler.apply(this,arguments)},teardown:function(){f.event.remove(this,"._change");return z.test(this.nodeName)}}),f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){var d=0,e=function(a){f.event.simulate(b,a.target,f.event.fix(a),!0)};f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.fn.extend({on:function(a,c,d,e,g){var h,i;if(typeof a=="object"){typeof c!="string"&&(d=d||c,c=b);for(i in a)this.on(i,c,d,a[i],g);return this}d==null&&e==null?(e=c,d=c=b):e==null&&(typeof c=="string"?(e=d,d=b):(e=d,d=c,c=b));if(e===!1)e=J;else if(!e)return this;g===1&&(h=e,e=function(a){f().off(a);return h.apply(this,arguments)},e.guid=h.guid||(h.guid=f.guid++));return this.each(function(){f.event.add(this,a,e,d,c)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,c,d){if(a&&a.preventDefault&&a.handleObj){var e=a.handleObj;f(a.delegateTarget).off(e.namespace?e.origType+"."+e.namespace:e.origType,e.selector,e.handler);return this}if(typeof a=="object"){for(var g in a)this.off(g,c,a[g]);return this}if(c===!1||typeof c=="function")d=c,c=b;d===!1&&(d=J);return this.each(function(){f.event.remove(this,a,d,c)})},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},live:function(a,b,c){f(this.context).on(a,this.selector,b,c);return this},die:function(a,b){f(this.context).off(a,this.selector||"**",b);return this},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return arguments.length==1?this.off(a,"**"):this.off(b,a,c)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f._data(this,"lastToggle"+a.guid)||0)%d;f._data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.on(b,null,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0),C.test(b)&&(f.event.fixHooks[b]=f.event.keyHooks),D.test(b)&&(f.event.fixHooks[b]=f.event.mouseHooks)}),function(){function x(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}if(j.nodeType===1){g||(j[d]=c,j.sizset=h);if(typeof b!="string"){if(j===b){k=!0;break}}else if(m.filter(b,[j]).length>0){k=j;break}}j=j[a]}e[h]=k}}}function w(a,b,c,e,f,g){for(var h=0,i=e.length;h<i;h++){var j=e[h];if(j){var k=!1;j=j[a];while(j){if(j[d]===c){k=e[j.sizset];break}j.nodeType===1&&!g&&(j[d]=c,j.sizset=h);if(j.nodeName.toLowerCase()===b){k=j;break}j=j[a]}e[h]=k}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d="sizcache"+(Math.random()+"").replace(".",""),e=0,g=Object.prototype.toString,h=!1,i=!0,j=/\\/g,k=/\r\n/g,l=/\W/;[0,0].sort(function(){i=!1;return 0});var m=function(b,d,e,f){e=e||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return e;var i,j,k,l,n,q,r,t,u=!0,v=m.isXML(d),w=[],x=b;do{a.exec(""),i=a.exec(x);if(i){x=i[3],w.push(i[1]);if(i[2]){l=i[3];break}}}while(i);if(w.length>1&&p.exec(b))if(w.length===2&&o.relative[w[0]])j=y(w[0]+w[1],d,f);else{j=o.relative[w[0]]?[d]:m(w.shift(),d);while(w.length)b=w.shift(),o.relative[b]&&(b+=w.shift()),j=y(b,j,f)}else{!f&&w.length>1&&d.nodeType===9&&!v&&o.match.ID.test(w[0])&&!o.match.ID.test(w[w.length-1])&&(n=m.find(w.shift(),d,v),d=n.expr?m.filter(n.expr,n.set)[0]:n.set[0]);if(d){n=f?{expr:w.pop(),set:s(f)}:m.find(w.pop(),w.length===1&&(w[0]==="~"||w[0]==="+")&&d.parentNode?d.parentNode:d,v),j=n.expr?m.filter(n.expr,n.set):n.set,w.length>0?k=s(j):u=!1;while(w.length)q=w.pop(),r=q,o.relative[q]?r=w.pop():q="",r==null&&(r=d),o.relative[q](k,r,v)}else k=w=[]}k||(k=j),k||m.error(q||b);if(g.call(k)==="[object Array]")if(!u)e.push.apply(e,k);else if(d&&d.nodeType===1)for(t=0;k[t]!=null;t++)k[t]&&(k[t]===!0||k[t].nodeType===1&&m.contains(d,k[t]))&&e.push(j[t]);else for(t=0;k[t]!=null;t++)k[t]&&k[t].nodeType===1&&e.push(j[t]);else s(k,e);l&&(m(l,h,e,f),m.uniqueSort(e));return e};m.uniqueSort=function(a){if(u){h=i,a.sort(u);if(h)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},m.matches=function(a,b){return m(a,null,null,b)},m.matchesSelector=function(a,b){return m(b,null,null,[a]).length>0},m.find=function(a,b,c){var d,e,f,g,h,i;if(!a)return[];for(e=0,f=o.order.length;e<f;e++){h=o.order[e];if(g=o.leftMatch[h].exec(a)){i=g[1],g.splice(1,1);if(i.substr(i.length-1)!=="\\"){g[1]=(g[1]||"").replace(j,""),d=o.find[h](g,b,c);if(d!=null){a=a.replace(o.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},m.filter=function(a,c,d,e){var f,g,h,i,j,k,l,n,p,q=a,r=[],s=c,t=c&&c[0]&&m.isXML(c[0]);while(a&&c.length){for(h in o.filter)if((f=o.leftMatch[h].exec(a))!=null&&f[2]){k=o.filter[h],l=f[1],g=!1,f.splice(1,1);if(l.substr(l.length-1)==="\\")continue;s===r&&(r=[]);if(o.preFilter[h]){f=o.preFilter[h](f,s,d,r,e,t);if(!f)g=i=!0;else if(f===!0)continue}if(f)for(n=0;(j=s[n])!=null;n++)j&&(i=k(j,f,n,s),p=e^i,d&&i!=null?p?g=!0:s[n]=!1:p&&(r.push(j),g=!0));if(i!==b){d||(s=r),a=a.replace(o.match[h],"");if(!g)return[];break}}if(a===q)if(g==null)m.error(a);else break;q=a}return s},m.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)};var n=m.getText=function(a){var b,c,d=a.nodeType,e="";if(d){if(d===1||d===9||d===11){if(typeof a.textContent=="string")return a.textContent;if(typeof a.innerText=="string")return a.innerText.replace(k,"");for(a=a.firstChild;a;a=a.nextSibling)e+=n(a)}else if(d===3||d===4)return a.nodeValue}else for(b=0;c=a[b];b++)c.nodeType!==8&&(e+=n(c));return e},o=m.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!l.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&m.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!l.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&m.filter(b,a,!0)}},"":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("parentNode",b,f,a,d,c)},"~":function(a,b,c){var d,f=e++,g=x;typeof b=="string"&&!l.test(b)&&(b=b.toLowerCase(),d=b,g=w),g("previousSibling",b,f,a,d,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(j,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(j,"")},TAG:function(a,b){return a[1].replace(j,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||m.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&m.error(a[0]);a[0]=e++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(j,"");!f&&o.attrMap[g]&&(a[1]=o.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(j,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=m(b[3],null,null,c);else{var g=m.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(o.match.POS.test(b[0])||o.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!m(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=o.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||n([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}m.error(e)},CHILD:function(a,b){var c,e,f,g,h,i,j,k=b[1],l=a;switch(k){case"only":case"first":while(l=l.previousSibling)if(l.nodeType===1)return!1;if(k==="first")return!0;l=a;case"last":while(l=l.nextSibling)if(l.nodeType===1)return!1;return!0;case"nth":c=b[2],e=b[3];if(c===1&&e===0)return!0;f=b[0],g=a.parentNode;if(g&&(g[d]!==f||!a.nodeIndex)){i=0;for(l=g.firstChild;l;l=l.nextSibling)l.nodeType===1&&(l.nodeIndex=++i);g[d]=f}j=a.nodeIndex-e;return c===0?j===0:j%c===0&&j/c>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||!!a.nodeName&&a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=m.attr?m.attr(a,c):o.attrHandle[c]?o.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":!f&&m.attr?d!=null:f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=o.setFilters[e];if(f)return f(a,c,b,d)}}},p=o.match.POS,q=function(a,b){return"\\"+(b-0+1)};for(var r in o.match)o.match[r]=new RegExp(o.match[r].source+/(?![^\[]*\])(?![^\(]*\))/.source),o.leftMatch[r]=new RegExp(/(^(?:.|\r|\n)*?)/.source+o.match[r].source.replace(/\\(\d+)/g,q));o.match.globalPOS=p;var s=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(t){s=function(a,b){var c=0,d=b||[];if(g.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var e=a.length;c<e;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var u,v;c.documentElement.compareDocumentPosition?u=function(a,b){if(a===b){h=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(u=function(a,b){if(a===b){h=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],g=a.parentNode,i=b.parentNode,j=g;if(g===i)return v(a,b);if(!g)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return v(e[k],f[k]);return k===c?v(a,f[k],-1):v(e[k],b,1)},v=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(o.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},o.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(o.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(o.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=m,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){m=function(b,e,f,g){e=e||c;if(!g&&!m.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return s(e.getElementsByTagName(b),f);if(h[2]&&o.find.CLASS&&e.getElementsByClassName)return s(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return s([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return s([],f);if(i.id===h[3])return s([i],f)}try{return s(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var k=e,l=e.getAttribute("id"),n=l||d,p=e.parentNode,q=/^\s*[+~]/.test(b);l?n=n.replace(/'/g,"\\$&"):e.setAttribute("id",n),q&&p&&(e=e.parentNode);try{if(!q||p)return s(e.querySelectorAll("[id='"+n+"'] "+b),f)}catch(r){}finally{l||k.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)m[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}m.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!m.isXML(a))try{if(e||!o.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return m(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;o.order.splice(1,0,"CLASS"),o.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?m.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?m.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:m.contains=function(){return!1},m.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var y=function(a,b,c){var d,e=[],f="",g=b.nodeType?[b]:b;while(d=o.match.PSEUDO.exec(a))f+=d[0],a=a.replace(o.match.PSEUDO,"");a=o.relative[a]?a+"*":a;for(var h=0,i=g.length;h<i;h++)m(a,g[h],e,c);return m.filter(f,e)};m.attr=f.attr,m.selectors.attrMap={},f.find=m,f.expr=m.selectors,f.expr[":"]=f.expr.filters,f.unique=m.uniqueSort,f.text=m.getText,f.isXMLDoc=m.isXML,f.contains=m.contains}();var L=/Until$/,M=/^(?:parents|prevUntil|prevAll)/,N=/,/,O=/^.[^:#\[\.,]*$/,P=Array.prototype.slice,Q=f.expr.match.globalPOS,R={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(T(this,a,!1),"not",a)},filter:function(a){return this.pushStack(T(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?Q.test(a)?f(a,this.context).index(this[0])>=0:f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h=1;while(g&&g.ownerDocument&&g!==b){for(d=0;d<a.length;d++)f(g).is(a[d])&&c.push({selector:a[d],elem:g,level:h});g=g.parentNode,h++}return c}var i=Q.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(i?i.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a)return this[0]&&this[0].parentNode?this.prevAll().length:-1;if(typeof a=="string")return f.inArray(this[0],f(a));return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(S(c[0])||S(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c);L.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!R[a]?f.unique(e):e,(this.length>1||N.test(d))&&M.test(a)&&(e=e.reverse());return this.pushStack(e,a,P.call(arguments).join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var V="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",W=/ jQuery\d+="(?:\d+|null)"/g,X=/^\s+/,Y=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,Z=/<([\w:]+)/,$=/<tbody/i,_=/<|&#?\w+;/,ba=/<(?:script|style)/i,bb=/<(?:script|object|embed|option|style)/i,bc=new RegExp("<(?:"+V+")[\\s/>]","i"),bd=/checked\s*(?:[^=]|=\s*.checked.)/i,be=/\/(java|ecma)script/i,bf=/^\s*<!(?:\[CDATA\[|\-\-)/,bg={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},bh=U(c);bg.optgroup=bg.option,bg.tbody=bg.tfoot=bg.colgroup=bg.caption=bg.thead,bg.th=bg.td,f.support.htmlSerialize||(bg._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){return f.access(this,function(a){return a===b?f.text(this):this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a))},null,a,arguments.length)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=f.isFunction(a);return this.each(function(c){f(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f
|
4 |
+
.clean(arguments);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f.clean(arguments));return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){return f.access(this,function(a){var c=this[0]||{},d=0,e=this.length;if(a===b)return c.nodeType===1?c.innerHTML.replace(W,""):null;if(typeof a=="string"&&!ba.test(a)&&(f.support.leadingWhitespace||!X.test(a))&&!bg[(Z.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Y,"<$1></$2>");try{for(;d<e;d++)c=this[d]||{},c.nodeType===1&&(f.cleanData(c.getElementsByTagName("*")),c.innerHTML=a);c=0}catch(g){}}c&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bd.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bi(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,function(a,b){b.src?f.ajax({type:"GET",global:!1,url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(bf,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)})}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i,j=a[0];b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof j=="string"&&j.length<512&&i===c&&j.charAt(0)==="<"&&!bb.test(j)&&(f.support.checkClone||!bd.test(j))&&(f.support.html5Clone||!bc.test(j))&&(g=!0,h=f.fragments[j],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[j]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d,e,g,h=f.support.html5Clone||f.isXMLDoc(a)||!bc.test("<"+a.nodeName+">")?a.cloneNode(!0):bo(a);if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bk(a,h),d=bl(a),e=bl(h);for(g=0;d[g];++g)e[g]&&bk(d[g],e[g])}if(b){bj(a,h);if(c){d=bl(a),e=bl(h);for(g=0;d[g];++g)bj(d[g],e[g])}}d=e=null;return h},clean:function(a,b,d,e){var g,h,i,j=[];b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);for(var k=0,l;(l=a[k])!=null;k++){typeof l=="number"&&(l+="");if(!l)continue;if(typeof l=="string")if(!_.test(l))l=b.createTextNode(l);else{l=l.replace(Y,"<$1></$2>");var m=(Z.exec(l)||["",""])[1].toLowerCase(),n=bg[m]||bg._default,o=n[0],p=b.createElement("div"),q=bh.childNodes,r;b===c?bh.appendChild(p):U(b).appendChild(p),p.innerHTML=n[1]+l+n[2];while(o--)p=p.lastChild;if(!f.support.tbody){var s=$.test(l),t=m==="table"&&!s?p.firstChild&&p.firstChild.childNodes:n[1]==="<table>"&&!s?p.childNodes:[];for(i=t.length-1;i>=0;--i)f.nodeName(t[i],"tbody")&&!t[i].childNodes.length&&t[i].parentNode.removeChild(t[i])}!f.support.leadingWhitespace&&X.test(l)&&p.insertBefore(b.createTextNode(X.exec(l)[0]),p.firstChild),l=p.childNodes,p&&(p.parentNode.removeChild(p),q.length>0&&(r=q[q.length-1],r&&r.parentNode&&r.parentNode.removeChild(r)))}var u;if(!f.support.appendChecked)if(l[0]&&typeof (u=l.length)=="number")for(i=0;i<u;i++)bn(l[i]);else bn(l);l.nodeType?j.push(l):j=f.merge(j,l)}if(d){g=function(a){return!a.type||be.test(a.type)};for(k=0;j[k];k++){h=j[k];if(e&&f.nodeName(h,"script")&&(!h.type||be.test(h.type)))e.push(h.parentNode?h.parentNode.removeChild(h):h);else{if(h.nodeType===1){var v=f.grep(h.getElementsByTagName("script"),g);j.splice.apply(j,[k+1,0].concat(v))}d.appendChild(h)}}}return j},cleanData:function(a){var b,c,d=f.cache,e=f.event.special,g=f.support.deleteExpando;for(var h=0,i;(i=a[h])!=null;h++){if(i.nodeName&&f.noData[i.nodeName.toLowerCase()])continue;c=i[f.expando];if(c){b=d[c];if(b&&b.events){for(var j in b.events)e[j]?f.event.remove(i,j):f.removeEvent(i,j,b.handle);b.handle&&(b.handle.elem=null)}g?delete i[f.expando]:i.removeAttribute&&i.removeAttribute(f.expando),delete d[c]}}}});var bp=/alpha\([^)]*\)/i,bq=/opacity=([^)]*)/,br=/([A-Z]|^ms)/g,bs=/^[\-+]?(?:\d*\.)?\d+$/i,bt=/^-?(?:\d*\.)?\d+(?!px)[^\d\s]+$/i,bu=/^([\-+])=([\-+.\de]+)/,bv=/^margin/,bw={position:"absolute",visibility:"hidden",display:"block"},bx=["Top","Right","Bottom","Left"],by,bz,bA;f.fn.css=function(a,c){return f.access(this,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)},a,c,arguments.length>1)},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=by(a,"opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d,h==="string"&&(g=bu.exec(d))&&(d=+(g[1]+1)*+g[2]+parseFloat(f.css(a,c)),h="number");if(d==null||h==="number"&&isNaN(d))return;h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(by)return by(a,c)},swap:function(a,b,c){var d={},e,f;for(f in b)d[f]=a.style[f],a.style[f]=b[f];e=c.call(a);for(f in b)a.style[f]=d[f];return e}}),f.curCSS=f.css,c.defaultView&&c.defaultView.getComputedStyle&&(bz=function(a,b){var c,d,e,g,h=a.style;b=b.replace(br,"-$1").toLowerCase(),(d=a.ownerDocument.defaultView)&&(e=d.getComputedStyle(a,null))&&(c=e.getPropertyValue(b),c===""&&!f.contains(a.ownerDocument.documentElement,a)&&(c=f.style(a,b))),!f.support.pixelMargin&&e&&bv.test(b)&&bt.test(c)&&(g=h.width,h.width=c,c=e.width,h.width=g);return c}),c.documentElement.currentStyle&&(bA=function(a,b){var c,d,e,f=a.currentStyle&&a.currentStyle[b],g=a.style;f==null&&g&&(e=g[b])&&(f=e),bt.test(f)&&(c=g.left,d=a.runtimeStyle&&a.runtimeStyle.left,d&&(a.runtimeStyle.left=a.currentStyle.left),g.left=b==="fontSize"?"1em":f,f=g.pixelLeft+"px",g.left=c,d&&(a.runtimeStyle.left=d));return f===""?"auto":f}),by=bz||bA,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){if(c)return a.offsetWidth!==0?bB(a,b,d):f.swap(a,bw,function(){return bB(a,b,d)})},set:function(a,b){return bs.test(b)?b+"px":b}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bq.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=f.isNumeric(b)?"alpha(opacity="+b*100+")":"",g=d&&d.filter||c.filter||"";c.zoom=1;if(b>=1&&f.trim(g.replace(bp,""))===""){c.removeAttribute("filter");if(d&&!d.filter)return}c.filter=bp.test(g)?g.replace(bp,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){return f.swap(a,{display:"inline-block"},function(){return b?by(a,"margin-right"):a.style.marginRight})}})}),f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style&&a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)}),f.each({margin:"",padding:"",border:"Width"},function(a,b){f.cssHooks[a+b]={expand:function(c){var d,e=typeof c=="string"?c.split(" "):[c],f={};for(d=0;d<4;d++)f[a+bx[d]+b]=e[d]||e[d-2]||e[0];return f}}});var bC=/%20/g,bD=/\[\]$/,bE=/\r?\n/g,bF=/#.*$/,bG=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bH=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bI=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,bJ=/^(?:GET|HEAD)$/,bK=/^\/\//,bL=/\?/,bM=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bN=/^(?:select|textarea)/i,bO=/\s+/,bP=/([?&])_=[^&]*/,bQ=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bR=f.fn.load,bS={},bT={},bU,bV,bW=["*/"]+["*"];try{bU=e.href}catch(bX){bU=c.createElement("a"),bU.href="",bU=bU.href}bV=bQ.exec(bU.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bR)return bR.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bM,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bN.test(this.nodeName)||bH.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bE,"\r\n")}}):{name:b.name,value:c.replace(bE,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.on(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?b$(a,f.ajaxSettings):(b=a,a=f.ajaxSettings),b$(a,b);return a},ajaxSettings:{url:bU,isLocal:bI.test(bV[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded; charset=UTF-8",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":bW},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:bY(bS),ajaxTransport:bY(bT),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a>0?4:0;var o,r,u,w=c,x=l?ca(d,v,l):b,y,z;if(a>=200&&a<300||a===304){if(d.ifModified){if(y=v.getResponseHeader("Last-Modified"))f.lastModified[k]=y;if(z=v.getResponseHeader("Etag"))f.etag[k]=z}if(a===304)w="notmodified",o=!0;else try{r=cb(d,x),w="success",o=!0}catch(A){w="parsererror",u=A}}else{u=w;if(!w||a)w="error",a<0&&(a=0)}v.status=a,v.statusText=""+(c||w),o?h.resolveWith(e,[r,w,v]):h.rejectWith(e,[v,w,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.fireWith(e,[v,w]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f.Callbacks("once memory"),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bG.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.add,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bF,"").replace(bK,bV[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bO),d.crossDomain==null&&(r=bQ.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bV[1]&&r[2]==bV[2]&&(r[3]||(r[1]==="http:"?80:443))==(bV[3]||(bV[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bZ(bS,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bJ.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bL.test(d.url)?"&":"?")+d.data,delete d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bP,"$1_="+x);d.url=y+(y===d.url?(bL.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", "+bW+"; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bZ(bT,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){if(s<2)w(-1,z);else throw z}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)b_(g,a[g],c,e);return d.join("&").replace(bC,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var cc=f.now(),cd=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+cc++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=typeof b.data=="string"&&/^application\/x\-www\-form\-urlencoded/.test(b.contentType);if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(cd.test(b.url)||e&&cd.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(cd,l),b.url===j&&(e&&(k=k.replace(cd,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var ce=a.ActiveXObject?function(){for(var a in cg)cg[a](0,1)}:!1,cf=0,cg;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ch()||ci()}:ch,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,ce&&delete cg[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n);try{m.text=h.responseText}catch(a){}try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cf,ce&&(cg||(cg={},f(a).unload(ce)),cg[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cj={},ck,cl,cm=/^(?:toggle|show|hide)$/,cn=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,co,cp=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cq;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(ct("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),(e===""&&f.css(d,"display")==="none"||!f.contains(d.ownerDocument.documentElement,d))&&f._data(d,"olddisplay",cu(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(ct("hide",3),a,b,c);var d,e,g=0,h=this.length;for(;g<h;g++)d=this[g],d.style&&(e=f.css(d,"display"),e!=="none"&&!f._data(d,"olddisplay")&&f._data(d,"olddisplay",e));for(g=0;g<h;g++)this[g].style&&(this[g].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(ct("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){function g(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o,p,q;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]);if((k=f.cssHooks[g])&&"expand"in k){l=k.expand(a[g]),delete a[g];for(i in l)i in a||(a[i]=l[i])}}for(g in a){h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(!f.support.inlineBlockNeedsLayout||cu(this.nodeName)==="inline"?this.style.display="inline-block":this.style.zoom=1))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)j=new f.fx(this,b,i),h=a[i],cm.test(h)?(q=f._data(this,"toggle"+i)||(h==="toggle"?d?"show":"hide":0),q?(f._data(this,"toggle"+i,q==="show"?"hide":"show"),j[q]()):j[h]()):(m=cn.exec(h),n=j.cur(),m?(o=parseFloat(m[2]),p=m[3]||(f.cssNumber[i]?"":"px"),p!=="px"&&(f.style(this,i,(o||1)+p),n=(o||1)/j.cur()*n,f.style(this,i,n+p)),m[1]&&(o=(m[1]==="-="?-1:1)*o+n),j.custom(n,o,p)):j.custom(n,h,""));return!0}var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return e.queue===!1?this.each(g):this.queue(e.queue,g)},stop:function(a,c,d){typeof a!="string"&&(d=c,c=a,a=b),c&&a!==!1&&this.queue(a||"fx",[]);return this.each(function(){function h(a,b,c){var e=b[c];f.removeData(a,c,!0),e.stop(d)}var b,c=!1,e=f.timers,g=f._data(this);d||f._unmark(!0,this);if(a==null)for(b in g)g[b]&&g[b].stop&&b.indexOf(".run")===b.length-4&&h(this,g,b);else g[b=a+".run"]&&g[b].stop&&h(this,g,b);for(b=e.length;b--;)e[b].elem===this&&(a==null||e[b].queue===a)&&(d?e[b](!0):e[b].saveState(),c=!0,e.splice(b,1));(!d||!c)&&f.dequeue(this,a)})}}),f.each({slideDown:ct("show",1),slideUp:ct("hide",1),slideToggle:ct("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default;if(d.queue==null||d.queue===!0)d.queue="fx";d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue?f.dequeue(this,d.queue):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a){return a},swing:function(a){return-Math.cos(a*Math.PI)/2+.5}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,c,d){function h(a){return e.step(a)}var e=this,g=f.fx;this.startTime=cq||cr(),this.end=c,this.now=this.start=a,this.pos=this.state=0,this.unit=d||this.unit||(f.cssNumber[this.prop]?"":"px"),h.queue=this.options.queue,h.elem=this.elem,h.saveState=function(){f._data(e.elem,"fxshow"+e.prop)===b&&(e.options.hide?f._data(e.elem,"fxshow"+e.prop,e.start):e.options.show&&f._data(e.elem,"fxshow"+e.prop,e.end))},h()&&f.timers.push(h)&&!co&&(co=setInterval(g.tick,g.interval))},show:function(){var a=f._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=a||f.style(this.elem,this.prop),this.options.show=!0,a!==b?this.custom(this.cur(),a):this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f._data(this.elem,"fxshow"+this.prop)||f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b,c,d,e=cq||cr(),g=!0,h=this.elem,i=this.options;if(a||e>=i.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),i.animatedProperties[this.prop]=!0;for(b in i.animatedProperties)i.animatedProperties[b]!==!0&&(g=!1);if(g){i.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){h.style["overflow"+b]=i.overflow[a]}),i.hide&&f(h).hide();if(i.hide||i.show)for(b in i.animatedProperties)f.style(h,b,i.orig[b]),f.removeData(h,"fxshow"+b,!0),f.removeData(h,"toggle"+b,!0);d=i.complete,d&&(i.complete=!1,d.call(h))}return!1}i.duration==Infinity?this.now=e:(c=e-this.startTime,this.state=c/i.duration,this.pos=f.easing[i.animatedProperties[this.prop]](this.state,c,0,1,i.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){var a,b=f.timers,c=0;for(;c<b.length;c++)a=b[c],!a()&&b[c]===a&&b.splice(c--,1);b.length||f.fx.stop()},interval:13,stop:function(){clearInterval(co),co=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=a.now+a.unit:a.elem[a.prop]=a.now}}}),f.each(cp.concat.apply([],cp),function(a,b){b.indexOf("margin")&&(f.fx.step[b]=function(a){f.style(a.elem,b,Math.max(0,a.now)+a.unit)})}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var cv,cw=/^t(?:able|d|h)$/i,cx=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?cv=function(a,b,c,d){try{d=a.getBoundingClientRect()}catch(e){}if(!d||!f.contains(c,a))return d?{top:d.top,left:d.left}:{top:0,left:0};var g=b.body,h=cy(b),i=c.clientTop||g.clientTop||0,j=c.clientLeft||g.clientLeft||0,k=h.pageYOffset||f.support.boxModel&&c.scrollTop||g.scrollTop,l=h.pageXOffset||f.support.boxModel&&c.scrollLeft||g.scrollLeft,m=d.top+k-i,n=d.left+l-j;return{top:m,left:n}}:cv=function(a,b,c){var d,e=a.offsetParent,g=a,h=b.body,i=b.defaultView,j=i?i.getComputedStyle(a,null):a.currentStyle,k=a.offsetTop,l=a.offsetLeft;while((a=a.parentNode)&&a!==h&&a!==c){if(f.support.fixedPosition&&j.position==="fixed")break;d=i?i.getComputedStyle(a,null):a.currentStyle,k-=a.scrollTop,l-=a.scrollLeft,a===e&&(k+=a.offsetTop,l+=a.offsetLeft,f.support.doesNotAddBorder&&(!f.support.doesAddBorderForTableAndCells||!cw.test(a.nodeName))&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),g=e,e=a.offsetParent),f.support.subtractsBorderForOverflowNotVisible&&d.overflow!=="visible"&&(k+=parseFloat(d.borderTopWidth)||0,l+=parseFloat(d.borderLeftWidth)||0),j=d}if(j.position==="relative"||j.position==="static")k+=h.offsetTop,l+=h.offsetLeft;f.support.fixedPosition&&j.position==="fixed"&&(k+=Math.max(c.scrollTop,h.scrollTop),l+=Math.max(c.scrollLeft,h.scrollLeft));return{top:k,left:l}},f.fn.offset=function(a){if(arguments.length)return a===b?this:this.each(function(b){f.offset.setOffset(this,a,b)});var c=this[0],d=c&&c.ownerDocument;if(!d)return null;if(c===d.body)return f.offset.bodyOffset(c);return cv(c,d,d.documentElement)},f.offset={bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.support.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cx.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cx.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,c){var d=/Y/.test(c);f.fn[a]=function(e){return f.access(this,function(a,e,g){var h=cy(a);if(g===b)return h?c in h?h[c]:f.support.boxModel&&h.document.documentElement[e]||h.document.body[e]:a[e];h?h.scrollTo(d?f(h).scrollLeft():g,d?g:f(h).scrollTop()):a[e]=g},a,e,arguments.length,null)}}),f.each({Height:"height",Width:"width"},function(a,c){var d="client"+a,e="scroll"+a,g="offset"+a;f.fn["inner"+a]=function(){var a=this[0];return a?a.style?parseFloat(f.css(a,c,"padding")):this[c]():null},f.fn["outer"+a]=function(a){var b=this[0];return b?b.style?parseFloat(f.css(b,c,a?"margin":"border")):this[c]():null},f.fn[c]=function(a){return f.access(this,function(a,c,h){var i,j,k,l;if(f.isWindow(a)){i=a.document,j=i.documentElement[d];return f.support.boxModel&&j||i.body&&i.body[d]||j}if(a.nodeType===9){i=a.documentElement;if(i[d]>=i[e])return i[d];return Math.max(a.body[e],i[e],a.body[g],i[g])}if(h===b){k=f.css(a,c),l=parseFloat(k);return f.isNumeric(l)?l:k}f(a).css(c,h)},c,a,arguments.length,null)}}),a.jQuery=a.$=f,typeof define=="function"&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return f})})(window);
|
assets/fancyBox/lib/jquery.mousewheel-3.0.6.pack.js
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
|
2 |
+
* Licensed under the MIT License (LICENSE.txt).
|
3 |
+
*
|
4 |
+
* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
|
5 |
+
* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
|
6 |
+
* Thanks to: Seamus Leahy for adding deltaX and deltaY
|
7 |
+
*
|
8 |
+
* Version: 3.0.6
|
9 |
+
*
|
10 |
+
* Requires: 1.2.2+
|
11 |
+
*/
|
12 |
+
(function(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type="mousewheel";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;b.axis!==void 0&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);b.wheelDeltaY!==void 0&&(g=b.wheelDeltaY/120);b.wheelDeltaX!==void 0&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=["DOMMouseScroll","mousewheel"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=
|
13 |
+
d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,false);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,false);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery);
|
assets/fancyBox/source/blank.gif
ADDED
Binary file
|
assets/fancyBox/source/fancybox_loading.gif
ADDED
Binary file
|
assets/fancyBox/source/fancybox_sprite.png
ADDED
Binary file
|
assets/fancyBox/source/helpers/fancybox_buttons.png
ADDED
Binary file
|
assets/fancyBox/source/helpers/jquery.fancybox-buttons.css
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#fancybox-buttons {
|
2 |
+
position: fixed;
|
3 |
+
left: 0;
|
4 |
+
width: 100%;
|
5 |
+
z-index: 1005;
|
6 |
+
}
|
7 |
+
|
8 |
+
#fancybox-buttons.top {
|
9 |
+
top: 10px;
|
10 |
+
}
|
11 |
+
|
12 |
+
#fancybox-buttons.bottom {
|
13 |
+
bottom: 10px;
|
14 |
+
}
|
15 |
+
|
16 |
+
#fancybox-buttons ul {
|
17 |
+
display: block;
|
18 |
+
width: 170px;
|
19 |
+
height: 30px;
|
20 |
+
margin: 0 auto;
|
21 |
+
padding: 0;
|
22 |
+
list-style: none;
|
23 |
+
background: #111;
|
24 |
+
-webkit-box-shadow: 0 1px 3px #000,0 0 0 1px rgba(0,0,0,.7),inset 0 0 0 1px rgba(255,255,255,.05);
|
25 |
+
-moz-box-shadow: 0 1px 3px #000,0 0 0 1px rgba(0,0,0,.7),inset 0 0 0 1px rgba(255,255,255,.05);
|
26 |
+
background: #111 -webkit-gradient(linear,0% 0%,0% 100%,from(rgba(255,255,255,.2)),color-stop(.5,rgba(255,255,255,.15)),color-stop(.5,rgba(255,255,255,.1)),to(rgba(255,255,255,.15)));
|
27 |
+
background: #111 -moz-linear-gradient(top,rgba(255,255,255,.2) 0%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.1) 50%,rgba(255,255,255,.15) 100%);
|
28 |
+
border-radius: 3px;
|
29 |
+
}
|
30 |
+
|
31 |
+
#fancybox-buttons ul li {
|
32 |
+
float: left;
|
33 |
+
margin: 0;
|
34 |
+
padding: 0;
|
35 |
+
}
|
36 |
+
|
37 |
+
#fancybox-buttons a {
|
38 |
+
display: block;
|
39 |
+
width: 30px;
|
40 |
+
height: 30px;
|
41 |
+
text-indent: -9999px;
|
42 |
+
background-image: url('fancybox_buttons.png');
|
43 |
+
background-repeat: no-repeat;
|
44 |
+
outline: none;
|
45 |
+
}
|
46 |
+
|
47 |
+
#fancybox-buttons a.btnPrev {
|
48 |
+
width: 32px;
|
49 |
+
background-position: 6px 0;
|
50 |
+
}
|
51 |
+
|
52 |
+
#fancybox-buttons a.btnNext {
|
53 |
+
background-position: -33px 0;
|
54 |
+
border-right: 1px solid #3e3e3e;
|
55 |
+
}
|
56 |
+
|
57 |
+
#fancybox-buttons a.btnPlay {
|
58 |
+
background-position: 0 -30px;
|
59 |
+
}
|
60 |
+
|
61 |
+
#fancybox-buttons a.btnPlayOn {
|
62 |
+
background-position: -30px -30px;
|
63 |
+
}
|
64 |
+
|
65 |
+
#fancybox-buttons a.btnToggle {
|
66 |
+
background-position: 3px -60px;
|
67 |
+
border-left: 1px solid #111;
|
68 |
+
border-right: 1px solid #3e3e3e;
|
69 |
+
width: 35px
|
70 |
+
}
|
71 |
+
|
72 |
+
#fancybox-buttons a.btnToggleOn {
|
73 |
+
background-position: -27px -60px;
|
74 |
+
}
|
75 |
+
|
76 |
+
#fancybox-buttons a.btnClose {
|
77 |
+
border-left: 1px solid #111;
|
78 |
+
width: 38px;
|
79 |
+
background-position: -57px 0px;
|
80 |
+
}
|
81 |
+
|
82 |
+
#fancybox-buttons a.btnDisabled {
|
83 |
+
opacity : 0.5;
|
84 |
+
cursor: default;
|
85 |
+
}
|
assets/fancyBox/source/helpers/jquery.fancybox-buttons.js
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Buttons helper for fancyBox
|
3 |
+
* version: 1.0.2
|
4 |
+
* @requires fancyBox v2.0 or later
|
5 |
+
*
|
6 |
+
* Usage:
|
7 |
+
* $(".fancybox").fancybox({
|
8 |
+
* buttons: {
|
9 |
+
* position : 'top'
|
10 |
+
* }
|
11 |
+
* });
|
12 |
+
*
|
13 |
+
* Options:
|
14 |
+
* tpl - HTML template
|
15 |
+
* position - 'top' or 'bottom'
|
16 |
+
*
|
17 |
+
*/
|
18 |
+
(function ($) {
|
19 |
+
//Shortcut for fancyBox object
|
20 |
+
var F = $.fancybox;
|
21 |
+
|
22 |
+
//Add helper object
|
23 |
+
F.helpers.buttons = {
|
24 |
+
tpl: '<div id="fancybox-buttons"><ul><li><a class="btnPrev" title="Previous" href="javascript:;"></a></li><li><a class="btnPlay" title="Start slideshow" href="javascript:;"></a></li><li><a class="btnNext" title="Next" href="javascript:;"></a></li><li><a class="btnToggle" title="Toggle size" href="javascript:;"></a></li><li><a class="btnClose" title="Close" href="javascript:jQuery.fancybox.close();"></a></li></ul></div>',
|
25 |
+
list: null,
|
26 |
+
buttons: {},
|
27 |
+
|
28 |
+
update: function () {
|
29 |
+
var toggle = this.buttons.toggle.removeClass('btnDisabled btnToggleOn');
|
30 |
+
|
31 |
+
//Size toggle button
|
32 |
+
if (F.current.canShrink) {
|
33 |
+
toggle.addClass('btnToggleOn');
|
34 |
+
|
35 |
+
} else if (!F.current.canExpand) {
|
36 |
+
toggle.addClass('btnDisabled');
|
37 |
+
}
|
38 |
+
},
|
39 |
+
|
40 |
+
beforeLoad: function (opts) {
|
41 |
+
//Remove self if gallery do not have at least two items
|
42 |
+
if (F.group.length < 2) {
|
43 |
+
F.coming.helpers.buttons = false;
|
44 |
+
F.coming.closeBtn = true;
|
45 |
+
|
46 |
+
return;
|
47 |
+
}
|
48 |
+
|
49 |
+
//Increase top margin to give space for buttons
|
50 |
+
F.coming.margin[ opts.position === 'bottom' ? 2 : 0 ] += 30;
|
51 |
+
},
|
52 |
+
|
53 |
+
onPlayStart: function () {
|
54 |
+
if (this.list) {
|
55 |
+
this.buttons.play.attr('title', 'Pause slideshow').addClass('btnPlayOn');
|
56 |
+
}
|
57 |
+
},
|
58 |
+
|
59 |
+
onPlayEnd: function () {
|
60 |
+
if (this.list) {
|
61 |
+
this.buttons.play.attr('title', 'Start slideshow').removeClass('btnPlayOn');
|
62 |
+
}
|
63 |
+
},
|
64 |
+
|
65 |
+
afterShow: function (opts) {
|
66 |
+
var buttons;
|
67 |
+
|
68 |
+
if (!this.list) {
|
69 |
+
this.list = $(opts.tpl || this.tpl).addClass(opts.position || 'top').appendTo('body');
|
70 |
+
|
71 |
+
this.buttons = {
|
72 |
+
prev : this.list.find('.btnPrev').click( F.prev ),
|
73 |
+
next : this.list.find('.btnNext').click( F.next ),
|
74 |
+
play : this.list.find('.btnPlay').click( F.play ),
|
75 |
+
toggle : this.list.find('.btnToggle').click( F.toggle )
|
76 |
+
}
|
77 |
+
}
|
78 |
+
|
79 |
+
buttons = this.buttons;
|
80 |
+
|
81 |
+
//Prev
|
82 |
+
if (F.current.index > 0 || F.current.loop) {
|
83 |
+
buttons.prev.removeClass('btnDisabled');
|
84 |
+
} else {
|
85 |
+
buttons.prev.addClass('btnDisabled');
|
86 |
+
}
|
87 |
+
|
88 |
+
//Next / Play
|
89 |
+
if (F.current.loop || F.current.index < F.group.length - 1) {
|
90 |
+
buttons.next.removeClass('btnDisabled');
|
91 |
+
buttons.play.removeClass('btnDisabled');
|
92 |
+
|
93 |
+
} else {
|
94 |
+
buttons.next.addClass('btnDisabled');
|
95 |
+
buttons.play.addClass('btnDisabled');
|
96 |
+
}
|
97 |
+
|
98 |
+
this.update();
|
99 |
+
},
|
100 |
+
|
101 |
+
onUpdate: function () {
|
102 |
+
this.update();
|
103 |
+
},
|
104 |
+
|
105 |
+
beforeClose: function () {
|
106 |
+
if (this.list) {
|
107 |
+
this.list.remove();
|
108 |
+
}
|
109 |
+
|
110 |
+
this.list = null;
|
111 |
+
this.buttons = {};
|
112 |
+
}
|
113 |
+
};
|
114 |
+
|
115 |
+
}(jQuery));
|
assets/fancyBox/source/helpers/jquery.fancybox-media.js
ADDED
@@ -0,0 +1,86 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Media helper for fancyBox
|
3 |
+
* version: 1.0.0
|
4 |
+
* @requires fancyBox v2.0 or later
|
5 |
+
*
|
6 |
+
* Usage:
|
7 |
+
* $(".fancybox").fancybox({
|
8 |
+
* media: {}
|
9 |
+
* });
|
10 |
+
*
|
11 |
+
* Supports:
|
12 |
+
* Youtube
|
13 |
+
* http://www.youtube.com/watch?v=opj24KnzrWo
|
14 |
+
* http://youtu.be/opj24KnzrWo
|
15 |
+
* Vimeo
|
16 |
+
* http://vimeo.com/25634903
|
17 |
+
* Metacafe
|
18 |
+
* http://www.metacafe.com/watch/7635964/dr_seuss_the_lorax_movie_trailer/
|
19 |
+
* http://www.metacafe.com/watch/7635964/
|
20 |
+
* Dailymotion
|
21 |
+
* http://www.dailymotion.com/video/xoytqh_dr-seuss-the-lorax-premiere_people
|
22 |
+
* Twitvid
|
23 |
+
* http://twitvid.com/QY7MD
|
24 |
+
* Twitpic
|
25 |
+
* http://twitpic.com/7p93st
|
26 |
+
* Instagram
|
27 |
+
* http://instagr.am/p/IejkuUGxQn/
|
28 |
+
* http://instagram.com/p/IejkuUGxQn/
|
29 |
+
* Google maps
|
30 |
+
* http://maps.google.com/maps?q=Eiffel+Tower,+Avenue+Gustave+Eiffel,+Paris,+France&t=h&z=17
|
31 |
+
* http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16
|
32 |
+
* http://maps.google.com/?ll=48.859463,2.292626&spn=0.000965,0.002642&t=m&z=19&layer=c&cbll=48.859524,2.292532&panoid=YJ0lq28OOy3VT2IqIuVY0g&cbp=12,151.58,,0,-15.56
|
33 |
+
*/
|
34 |
+
(function ($) {
|
35 |
+
//Shortcut for fancyBox object
|
36 |
+
var F = $.fancybox;
|
37 |
+
|
38 |
+
//Add helper object
|
39 |
+
F.helpers.media = {
|
40 |
+
beforeLoad : function(opts, obj) {
|
41 |
+
var href = obj.href || '',
|
42 |
+
type = false,
|
43 |
+
rez;
|
44 |
+
|
45 |
+
if ((rez = href.match(/(youtube\.com|youtu\.be)\/(v\/|u\/|embed\/|watch\?v=)?([^#\&\?]*).*/i))) {
|
46 |
+
href = '//www.youtube.com/embed/' + rez[3] + '?autoplay=1&fs=1&rel=0&modestbranding=1&enablejsapi=1';
|
47 |
+
type = 'iframe';
|
48 |
+
|
49 |
+
} else if ((rez = href.match(/vimeo.com\/(\d+)\/?(.*)/))) {
|
50 |
+
href = '//player.vimeo.com/video/' + rez[1] + '?hd=1&autoplay=1&show_title=1&show_byline=1&show_portrait=0&color=&fullscreen=1';
|
51 |
+
type = 'iframe';
|
52 |
+
|
53 |
+
} else if ((rez = href.match(/metacafe.com\/watch\/(\d+)\/?(.*)/))) {
|
54 |
+
href = '//www.metacafe.com/fplayer/' + rez[1] + '/.swf?playerVars=autoPlay=yes';
|
55 |
+
type = 'swf';
|
56 |
+
|
57 |
+
} else if ((rez = href.match(/dailymotion.com\/video\/(.*)\/?(.*)/))) {
|
58 |
+
href = '//www.dailymotion.com/swf/video/' + rez[1] + '?additionalInfos=0&autoStart=1';
|
59 |
+
type = 'swf';
|
60 |
+
|
61 |
+
} else if ((rez = href.match(/twitvid\.com\/([a-zA-Z0-9_\-\?\=]+)/i))) {
|
62 |
+
href = '//www.twitvid.com/embed.php?autoplay=0&guid=' + rez[1];
|
63 |
+
type = 'iframe';
|
64 |
+
|
65 |
+
} else if ((rez = href.match(/twitpic\.com\/(?!(?:place|photos|events)\/)([a-zA-Z0-9\?\=\-]+)/i))) {
|
66 |
+
href = '//twitpic.com/show/full/' + rez[1];
|
67 |
+
type = 'image';
|
68 |
+
|
69 |
+
} else if ((rez = href.match(/(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i))) {
|
70 |
+
href = '//' + rez[1] + '/p/' + rez[2] + '/media/?size=l';
|
71 |
+
type = 'image';
|
72 |
+
|
73 |
+
} else if ((rez = href.match(/maps\.google\.com\/(\?ll=|maps\/?\?q=)(.*)/i))) {
|
74 |
+
href = '//maps.google.com/' + rez[1] + '' + rez[2] + '&output=' + (rez[2].indexOf('layer=c') ? 'svembed' : 'embed');
|
75 |
+
type = 'iframe';
|
76 |
+
}
|
77 |
+
|
78 |
+
if (type) {
|
79 |
+
obj.href = href;
|
80 |
+
obj.type = type;
|
81 |
+
obj.autoSize = false;
|
82 |
+
}
|
83 |
+
}
|
84 |
+
}
|
85 |
+
|
86 |
+
}(jQuery));
|
assets/fancyBox/source/helpers/jquery.fancybox-thumbs.css
ADDED
@@ -0,0 +1,54 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#fancybox-thumbs {
|
2 |
+
position: fixed;
|
3 |
+
left: 0px;
|
4 |
+
width: 100%;
|
5 |
+
overflow: hidden;
|
6 |
+
z-index: 1005;
|
7 |
+
}
|
8 |
+
|
9 |
+
#fancybox-thumbs.bottom {
|
10 |
+
bottom: 2px;
|
11 |
+
}
|
12 |
+
|
13 |
+
#fancybox-thumbs.top {
|
14 |
+
top: 2px;
|
15 |
+
}
|
16 |
+
|
17 |
+
#fancybox-thumbs ul {
|
18 |
+
position: relative;
|
19 |
+
list-style: none;
|
20 |
+
margin: 0;
|
21 |
+
padding: 0;
|
22 |
+
}
|
23 |
+
|
24 |
+
#fancybox-thumbs ul li {
|
25 |
+
float: left;
|
26 |
+
padding: 1px;
|
27 |
+
opacity: 0.5;
|
28 |
+
}
|
29 |
+
|
30 |
+
#fancybox-thumbs ul li.active {
|
31 |
+
opacity: 0.75;
|
32 |
+
padding: 0;
|
33 |
+
border: 1px solid #fff;
|
34 |
+
}
|
35 |
+
|
36 |
+
#fancybox-thumbs ul li:hover {
|
37 |
+
opacity: 1;
|
38 |
+
}
|
39 |
+
|
40 |
+
#fancybox-thumbs ul li a {
|
41 |
+
display: block;
|
42 |
+
position: relative;
|
43 |
+
overflow: hidden;
|
44 |
+
border: 1px solid #222;
|
45 |
+
background: #111;
|
46 |
+
outline: none;
|
47 |
+
}
|
48 |
+
|
49 |
+
#fancybox-thumbs ul li img {
|
50 |
+
display: block;
|
51 |
+
position: relative;
|
52 |
+
border: 0;
|
53 |
+
padding: 0;
|
54 |
+
}
|
assets/fancyBox/source/helpers/jquery.fancybox-thumbs.js
ADDED
@@ -0,0 +1,157 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* Thumbnail helper for fancyBox
|
3 |
+
* version: 1.0.4
|
4 |
+
* @requires fancyBox v2.0 or later
|
5 |
+
*
|
6 |
+
* Usage:
|
7 |
+
* $(".fancybox").fancybox({
|
8 |
+
* thumbs: {
|
9 |
+
* width : 50,
|
10 |
+
* height : 50
|
11 |
+
* }
|
12 |
+
* });
|
13 |
+
*
|
14 |
+
* Options:
|
15 |
+
* width - thumbnail width
|
16 |
+
* height - thumbnail height
|
17 |
+
* source - function to obtain the URL of the thumbnail image
|
18 |
+
* position - 'top' or 'bottom'
|
19 |
+
*
|
20 |
+
*/
|
21 |
+
(function ($) {
|
22 |
+
//Shortcut for fancyBox object
|
23 |
+
var F = $.fancybox;
|
24 |
+
|
25 |
+
//Add helper object
|
26 |
+
F.helpers.thumbs = {
|
27 |
+
wrap: null,
|
28 |
+
list: null,
|
29 |
+
width: 0,
|
30 |
+
|
31 |
+
//Default function to obtain the URL of the thumbnail image
|
32 |
+
source: function (el) {
|
33 |
+
var img;
|
34 |
+
|
35 |
+
if ($.type(el) === 'string') {
|
36 |
+
return el;
|
37 |
+
}
|
38 |
+
|
39 |
+
img = $(el).find('img');
|
40 |
+
|
41 |
+
return img.length ? img.attr('src') : el.href;
|
42 |
+
},
|
43 |
+
|
44 |
+
init: function (opts) {
|
45 |
+
var that = this,
|
46 |
+
list,
|
47 |
+
thumbWidth = opts.width || 50,
|
48 |
+
thumbHeight = opts.height || 50,
|
49 |
+
thumbSource = opts.source || this.source;
|
50 |
+
|
51 |
+
//Build list structure
|
52 |
+
list = '';
|
53 |
+
|
54 |
+
for (var n = 0; n < F.group.length; n++) {
|
55 |
+
list += '<li><a style="width:' + thumbWidth + 'px;height:' + thumbHeight + 'px;" href="javascript:jQuery.fancybox.jumpto(' + n + ');"></a></li>';
|
56 |
+
}
|
57 |
+
|
58 |
+
this.wrap = $('<div id="fancybox-thumbs"></div>').addClass(opts.position || 'bottom').appendTo('body');
|
59 |
+
this.list = $('<ul>' + list + '</ul>').appendTo(this.wrap);
|
60 |
+
|
61 |
+
//Load each thumbnail
|
62 |
+
$.each(F.group, function (i) {
|
63 |
+
$("<img />").load(function () {
|
64 |
+
var width = this.width,
|
65 |
+
height = this.height,
|
66 |
+
widthRatio, heightRatio, parent;
|
67 |
+
|
68 |
+
if (!that.list || !width || !height) {
|
69 |
+
return;
|
70 |
+
}
|
71 |
+
|
72 |
+
//Calculate thumbnail width/height and center it
|
73 |
+
widthRatio = width / thumbWidth;
|
74 |
+
heightRatio = height / thumbHeight;
|
75 |
+
parent = that.list.children().eq(i).find('a');
|
76 |
+
|
77 |
+
if (widthRatio >= 1 && heightRatio >= 1) {
|
78 |
+
if (widthRatio > heightRatio) {
|
79 |
+
width = Math.floor(width / heightRatio);
|
80 |
+
height = thumbHeight;
|
81 |
+
|
82 |
+
} else {
|
83 |
+
width = thumbWidth;
|
84 |
+
height = Math.floor(height / widthRatio);
|
85 |
+
}
|
86 |
+
}
|
87 |
+
|
88 |
+
$(this).css({
|
89 |
+
width: width,
|
90 |
+
height: height,
|
91 |
+
top: Math.floor(thumbHeight / 2 - height / 2),
|
92 |
+
left: Math.floor(thumbWidth / 2 - width / 2)
|
93 |
+
});
|
94 |
+
|
95 |
+
parent.width(thumbWidth).height(thumbHeight);
|
96 |
+
|
97 |
+
$(this).hide().appendTo(parent).fadeIn(300);
|
98 |
+
|
99 |
+
}).attr('src', thumbSource( F.group[ i ] ));
|
100 |
+
});
|
101 |
+
|
102 |
+
//Set initial width
|
103 |
+
this.width = this.list.children().eq(0).outerWidth(true);
|
104 |
+
|
105 |
+
this.list.width(this.width * (F.group.length + 1)).css('left', Math.floor($(window).width() * 0.5 - (F.current.index * this.width + this.width * 0.5)));
|
106 |
+
},
|
107 |
+
|
108 |
+
//Center list
|
109 |
+
update: function (opts) {
|
110 |
+
if (this.list) {
|
111 |
+
this.list.stop(true).animate({
|
112 |
+
'left': Math.floor($(window).width() * 0.5 - (F.current.index * this.width + this.width * 0.5))
|
113 |
+
}, 150);
|
114 |
+
}
|
115 |
+
},
|
116 |
+
|
117 |
+
beforeLoad: function (opts) {
|
118 |
+
//Remove self if gallery do not have at least two items
|
119 |
+
if (F.group.length < 2) {
|
120 |
+
F.coming.helpers.thumbs = false;
|
121 |
+
|
122 |
+
return;
|
123 |
+
}
|
124 |
+
|
125 |
+
//Increase bottom margin to give space for thumbs
|
126 |
+
F.coming.margin[ opts.position === 'top' ? 0 : 2 ] = opts.height + 30;
|
127 |
+
},
|
128 |
+
|
129 |
+
afterShow: function (opts) {
|
130 |
+
//Check if exists and create or update list
|
131 |
+
if (this.list) {
|
132 |
+
this.update(opts);
|
133 |
+
|
134 |
+
} else {
|
135 |
+
this.init(opts);
|
136 |
+
}
|
137 |
+
|
138 |
+
//Set active element
|
139 |
+
this.list.children().removeClass('active').eq(F.current.index).addClass('active');
|
140 |
+
},
|
141 |
+
|
142 |
+
onUpdate: function () {
|
143 |
+
this.update();
|
144 |
+
},
|
145 |
+
|
146 |
+
beforeClose: function () {
|
147 |
+
if (this.wrap) {
|
148 |
+
this.wrap.remove();
|
149 |
+
}
|
150 |
+
|
151 |
+
this.wrap = null;
|
152 |
+
this.list = null;
|
153 |
+
this.width = 0;
|
154 |
+
}
|
155 |
+
}
|
156 |
+
|
157 |
+
}(jQuery));
|
assets/fancyBox/source/jquery.fancybox.css
ADDED
@@ -0,0 +1,226 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*! fancyBox v2.0.5 fancyapps.com | fancyapps.com/fancybox/#license */
|
2 |
+
.fancybox-tmp iframe, .fancybox-tmp object {
|
3 |
+
vertical-align: top;
|
4 |
+
padding: 0;
|
5 |
+
margin: 0;
|
6 |
+
}
|
7 |
+
|
8 |
+
.fancybox-wrap {
|
9 |
+
position: absolute;
|
10 |
+
top: 0;
|
11 |
+
left: 0;
|
12 |
+
z-index: 1002;
|
13 |
+
}
|
14 |
+
|
15 |
+
.fancybox-outer {
|
16 |
+
position: relative;
|
17 |
+
padding: 0;
|
18 |
+
margin: 0;
|
19 |
+
background: #f9f9f9;
|
20 |
+
color: #444;
|
21 |
+
text-shadow: none;
|
22 |
+
-webkit-border-radius: 4px;
|
23 |
+
-moz-border-radius: 4px;
|
24 |
+
border-radius: 4px;
|
25 |
+
}
|
26 |
+
|
27 |
+
.fancybox-opened {
|
28 |
+
z-index: 1003;
|
29 |
+
}
|
30 |
+
|
31 |
+
.fancybox-opened .fancybox-outer {
|
32 |
+
-webkit-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
|
33 |
+
-moz-box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
|
34 |
+
box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
|
35 |
+
}
|
36 |
+
|
37 |
+
.fancybox-inner {
|
38 |
+
width: 100%;
|
39 |
+
height: 100%;
|
40 |
+
padding: 0;
|
41 |
+
margin: 0;
|
42 |
+
position: relative;
|
43 |
+
outline: none;
|
44 |
+
overflow: hidden;
|
45 |
+
}
|
46 |
+
|
47 |
+
.fancybox-type-iframe .fancybox-inner {
|
48 |
+
-webkit-overflow-scrolling: touch
|
49 |
+
}
|
50 |
+
|
51 |
+
.fancybox-error {
|
52 |
+
color: #444;
|
53 |
+
font: 14px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;
|
54 |
+
margin: 0;
|
55 |
+
padding: 10px;
|
56 |
+
}
|
57 |
+
|
58 |
+
.fancybox-image, .fancybox-iframe {
|
59 |
+
display: block;
|
60 |
+
width: 100%;
|
61 |
+
height: 100%;
|
62 |
+
border: 0;
|
63 |
+
padding: 0;
|
64 |
+
margin: 0;
|
65 |
+
vertical-align: top;
|
66 |
+
}
|
67 |
+
|
68 |
+
.fancybox-image {
|
69 |
+
max-width: 100%;
|
70 |
+
max-height: 100%;
|
71 |
+
}
|
72 |
+
|
73 |
+
#fancybox-loading, .fancybox-close, .fancybox-prev span, .fancybox-next span {
|
74 |
+
background-image: url('fancybox_sprite.png');
|
75 |
+
}
|
76 |
+
|
77 |
+
#fancybox-loading {
|
78 |
+
position: fixed;
|
79 |
+
top: 50%;
|
80 |
+
left: 50%;
|
81 |
+
margin-top: -22px;
|
82 |
+
margin-left: -22px;
|
83 |
+
background-position: 0 -108px;
|
84 |
+
opacity: 0.8;
|
85 |
+
cursor: pointer;
|
86 |
+
z-index: 1010;
|
87 |
+
}
|
88 |
+
|
89 |
+
#fancybox-loading div {
|
90 |
+
width: 44px;
|
91 |
+
height: 44px;
|
92 |
+
background: url('fancybox_loading.gif') center center no-repeat;
|
93 |
+
}
|
94 |
+
|
95 |
+
.fancybox-close {
|
96 |
+
position: absolute;
|
97 |
+
top: -18px;
|
98 |
+
right: -18px;
|
99 |
+
width: 36px;
|
100 |
+
height: 36px;
|
101 |
+
cursor: pointer;
|
102 |
+
z-index: 1004;
|
103 |
+
}
|
104 |
+
|
105 |
+
.fancybox-nav {
|
106 |
+
position: absolute;
|
107 |
+
top: 0;
|
108 |
+
width: 40%;
|
109 |
+
height: 100%;
|
110 |
+
cursor: pointer;
|
111 |
+
background: transparent url('blank.gif'); /* helps IE */
|
112 |
+
z-index: 1003;
|
113 |
+
}
|
114 |
+
|
115 |
+
.fancybox-prev {
|
116 |
+
left: 0;
|
117 |
+
}
|
118 |
+
|
119 |
+
.fancybox-next {
|
120 |
+
right: 0;
|
121 |
+
}
|
122 |
+
|
123 |
+
.fancybox-nav span {
|
124 |
+
position: absolute;
|
125 |
+
top: 50%;
|
126 |
+
width: 36px;
|
127 |
+
height: 36px;
|
128 |
+
margin-top: -18px;
|
129 |
+
cursor: pointer;
|
130 |
+
z-index: 1003;
|
131 |
+
visibility: hidden;
|
132 |
+
}
|
133 |
+
|
134 |
+
.fancybox-prev span {
|
135 |
+
left: 20px;
|
136 |
+
background-position: 0 -36px;
|
137 |
+
}
|
138 |
+
|
139 |
+
.fancybox-next span {
|
140 |
+
right: 20px;
|
141 |
+
background-position: 0 -72px;
|
142 |
+
}
|
143 |
+
|
144 |
+
.fancybox-nav:hover span {
|
145 |
+
visibility: visible;
|
146 |
+
}
|
147 |
+
|
148 |
+
.fancybox-tmp {
|
149 |
+
position: absolute;
|
150 |
+
top: -9999px;
|
151 |
+
left: -9999px;
|
152 |
+
padding: 0;
|
153 |
+
overflow: visible;
|
154 |
+
visibility: hidden;
|
155 |
+
}
|
156 |
+
|
157 |
+
/* Overlay helper */
|
158 |
+
|
159 |
+
#fancybox-overlay {
|
160 |
+
position: absolute;
|
161 |
+
top: 0;
|
162 |
+
left: 0;
|
163 |
+
overflow: hidden;
|
164 |
+
display: none;
|
165 |
+
z-index: 1001;
|
166 |
+
background: #000;
|
167 |
+
}
|
168 |
+
|
169 |
+
/* Title helper */
|
170 |
+
|
171 |
+
.fancybox-title {
|
172 |
+
visibility: hidden;
|
173 |
+
font: normal 13px/20px "Helvetica Neue",Helvetica,Arial,sans-serif;
|
174 |
+
position: relative;
|
175 |
+
text-shadow: none;
|
176 |
+
z-index: 1005;
|
177 |
+
}
|
178 |
+
|
179 |
+
.fancybox-opened .fancybox-title {
|
180 |
+
visibility: visible;
|
181 |
+
}
|
182 |
+
|
183 |
+
.fancybox-title-float-wrap {
|
184 |
+
position: absolute;
|
185 |
+
bottom: 0;
|
186 |
+
right: 50%;
|
187 |
+
margin-bottom: -35px;
|
188 |
+
z-index: 1003;
|
189 |
+
text-align: center;
|
190 |
+
}
|
191 |
+
|
192 |
+
.fancybox-title-float-wrap .child {
|
193 |
+
display: inline-block;
|
194 |
+
margin-right: -100%;
|
195 |
+
padding: 2px 20px;
|
196 |
+
background: transparent; /* Fallback for web browsers that doesn't support RGBa */
|
197 |
+
background: rgba(0, 0, 0, 0.8);
|
198 |
+
-webkit-border-radius: 15px;
|
199 |
+
-moz-border-radius: 15px;
|
200 |
+
border-radius: 15px;
|
201 |
+
text-shadow: 0 1px 2px #222;
|
202 |
+
color: #FFF;
|
203 |
+
font-weight: bold;
|
204 |
+
line-height: 24px;
|
205 |
+
white-space: nowrap;
|
206 |
+
}
|
207 |
+
|
208 |
+
.fancybox-title-outside-wrap {
|
209 |
+
position: relative;
|
210 |
+
margin-top: 10px;
|
211 |
+
color: #fff;
|
212 |
+
}
|
213 |
+
|
214 |
+
.fancybox-title-inside-wrap {
|
215 |
+
margin-top: 10px;
|
216 |
+
}
|
217 |
+
|
218 |
+
.fancybox-title-over-wrap {
|
219 |
+
position: absolute;
|
220 |
+
bottom: 0;
|
221 |
+
left: 0;
|
222 |
+
color: #fff;
|
223 |
+
padding: 10px;
|
224 |
+
background: #000;
|
225 |
+
background: rgba(0, 0, 0, .8);
|
226 |
+
}
|
assets/fancyBox/source/jquery.fancybox.js
ADDED
@@ -0,0 +1,1449 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*!
|
2 |
+
* fancyBox - jQuery Plugin
|
3 |
+
* version: 2.0.5 (27/03/2012)
|
4 |
+
* @requires jQuery v1.6 or later
|
5 |
+
*
|
6 |
+
* Examples at http://fancyapps.com/fancybox/
|
7 |
+
* License: www.fancyapps.com/fancybox/#license
|
8 |
+
*
|
9 |
+
* Copyright 2012 Janis Skarnelis - janis@fancyapps.com
|
10 |
+
*
|
11 |
+
*/
|
12 |
+
(function (window, document, undefined) {
|
13 |
+
"use strict";
|
14 |
+
|
15 |
+
var $ = window.jQuery,
|
16 |
+
W = $(window),
|
17 |
+
D = $(document),
|
18 |
+
F = $.fancybox = function () {
|
19 |
+
F.open.apply( this, arguments );
|
20 |
+
},
|
21 |
+
didResize = false,
|
22 |
+
resizeTimer = null,
|
23 |
+
isMobile = document.createTouch !== undefined,
|
24 |
+
isString = function(str) {
|
25 |
+
return $.type(str) === "string";
|
26 |
+
},
|
27 |
+
isPercentage = function(str) {
|
28 |
+
return isString(str) && str.indexOf('%') > -1;
|
29 |
+
};
|
30 |
+
|
31 |
+
$.extend(F, {
|
32 |
+
// The current version of fancyBox
|
33 |
+
version: '2.0.5',
|
34 |
+
|
35 |
+
defaults: {
|
36 |
+
padding: 15,
|
37 |
+
margin: 20,
|
38 |
+
|
39 |
+
width: 800,
|
40 |
+
height: 600,
|
41 |
+
minWidth: 100,
|
42 |
+
minHeight: 100,
|
43 |
+
maxWidth: 9999,
|
44 |
+
maxHeight: 9999,
|
45 |
+
|
46 |
+
autoSize: true,
|
47 |
+
autoResize: !isMobile,
|
48 |
+
autoCenter : !isMobile,
|
49 |
+
fitToView: true,
|
50 |
+
aspectRatio: false,
|
51 |
+
topRatio: 0.5,
|
52 |
+
|
53 |
+
fixed: !($.browser.msie && $.browser.version <= 6) && !isMobile,
|
54 |
+
scrolling: 'auto', // 'auto', 'yes' or 'no'
|
55 |
+
wrapCSS: 'fancybox-default',
|
56 |
+
|
57 |
+
arrows: true,
|
58 |
+
closeBtn: true,
|
59 |
+
closeClick: false,
|
60 |
+
nextClick : false,
|
61 |
+
mouseWheel: true,
|
62 |
+
autoPlay: false,
|
63 |
+
playSpeed: 3000,
|
64 |
+
preload : 3,
|
65 |
+
|
66 |
+
modal: false,
|
67 |
+
loop: true,
|
68 |
+
ajax: { dataType: 'html', headers: { 'X-fancyBox': true } },
|
69 |
+
keys: {
|
70 |
+
next: [13, 32, 34, 39, 40], // enter, space, page down, right arrow, down arrow
|
71 |
+
prev: [8, 33, 37, 38], // backspace, page up, left arrow, up arrow
|
72 |
+
close: [27] // escape key
|
73 |
+
},
|
74 |
+
|
75 |
+
// Override some properties
|
76 |
+
index: 0,
|
77 |
+
type: null,
|
78 |
+
href: null,
|
79 |
+
content: null,
|
80 |
+
title: null,
|
81 |
+
|
82 |
+
// HTML templates
|
83 |
+
tpl: {
|
84 |
+
wrap: '<div class="fancybox-wrap"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div>',
|
85 |
+
image: '<img class="fancybox-image" src="{href}" alt="" />',
|
86 |
+
iframe: '<iframe class="fancybox-iframe" name="fancybox-frame{rnd}" frameborder="0" hspace="0"' + ($.browser.msie ? ' allowtransparency="true"' : '') + '></iframe>',
|
87 |
+
swf: '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="wmode" value="transparent" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="{href}" /><embed src="{href}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="100%" height="100%" wmode="transparent"></embed></object>',
|
88 |
+
error: '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
|
89 |
+
closeBtn: '<div title="Close" class="fancybox-item fancybox-close"></div>',
|
90 |
+
next: '<a title="Next" class="fancybox-nav fancybox-next"><span></span></a>',
|
91 |
+
prev: '<a title="Previous" class="fancybox-nav fancybox-prev"><span></span></a>'
|
92 |
+
},
|
93 |
+
|
94 |
+
// Properties for each animation type
|
95 |
+
// Opening fancyBox
|
96 |
+
openEffect: 'fade', // 'elastic', 'fade' or 'none'
|
97 |
+
openSpeed: 250,
|
98 |
+
openEasing: 'swing',
|
99 |
+
openOpacity: true,
|
100 |
+
openMethod: 'zoomIn',
|
101 |
+
|
102 |
+
// Closing fancyBox
|
103 |
+
closeEffect: 'fade', // 'elastic', 'fade' or 'none'
|
104 |
+
closeSpeed: 250,
|
105 |
+
closeEasing: 'swing',
|
106 |
+
closeOpacity: true,
|
107 |
+
closeMethod: 'zoomOut',
|
108 |
+
|
109 |
+
// Changing next gallery item
|
110 |
+
nextEffect: 'elastic', // 'elastic', 'fade' or 'none'
|
111 |
+
nextSpeed: 300,
|
112 |
+
nextEasing: 'swing',
|
113 |
+
nextMethod: 'changeIn',
|
114 |
+
|
115 |
+
// Changing previous gallery item
|
116 |
+
prevEffect: 'elastic', // 'elastic', 'fade' or 'none'
|
117 |
+
prevSpeed: 300,
|
118 |
+
prevEasing: 'swing',
|
119 |
+
prevMethod: 'changeOut',
|
120 |
+
|
121 |
+
// Enabled helpers
|
122 |
+
helpers: {
|
123 |
+
overlay: {
|
124 |
+
speedIn: 0,
|
125 |
+
speedOut: 300,
|
126 |
+
opacity: 0.8,
|
127 |
+
css: {
|
128 |
+
cursor: 'pointer'
|
129 |
+
},
|
130 |
+
closeClick: true
|
131 |
+
},
|
132 |
+
title: {
|
133 |
+
type: 'float' // 'float', 'inside', 'outside' or 'over'
|
134 |
+
}
|
135 |
+
},
|
136 |
+
|
137 |
+
// Callbacks
|
138 |
+
onCancel: $.noop, // If canceling
|
139 |
+
beforeLoad: $.noop, // Before loading
|
140 |
+
afterLoad: $.noop, // After loading
|
141 |
+
beforeShow: $.noop, // Before changing in current item
|
142 |
+
afterShow: $.noop, // After opening
|
143 |
+
beforeClose: $.noop, // Before closing
|
144 |
+
afterClose: $.noop // After closing
|
145 |
+
},
|
146 |
+
|
147 |
+
//Current state
|
148 |
+
group: {}, // Selected group
|
149 |
+
opts: {}, // Group options
|
150 |
+
coming: null, // Element being loaded
|
151 |
+
current: null, // Currently loaded element
|
152 |
+
isOpen: false, // Is currently open
|
153 |
+
isOpened: false, // Have been fully opened at least once
|
154 |
+
wrap: null,
|
155 |
+
outer: null,
|
156 |
+
inner: null,
|
157 |
+
|
158 |
+
player: {
|
159 |
+
timer: null,
|
160 |
+
isActive: false
|
161 |
+
},
|
162 |
+
|
163 |
+
// Loaders
|
164 |
+
ajaxLoad: null,
|
165 |
+
imgPreload: null,
|
166 |
+
|
167 |
+
// Some collections
|
168 |
+
transitions: {},
|
169 |
+
helpers: {},
|
170 |
+
|
171 |
+
/*
|
172 |
+
* Static methods
|
173 |
+
*/
|
174 |
+
|
175 |
+
open: function (group, opts) {
|
176 |
+
//Kill existing instances
|
177 |
+
F.close(true);
|
178 |
+
|
179 |
+
//Normalize group
|
180 |
+
if (group && !$.isArray(group)) {
|
181 |
+
group = group instanceof $ ? $(group).get() : [group];
|
182 |
+
}
|
183 |
+
|
184 |
+
F.isActive = true;
|
185 |
+
|
186 |
+
//Extend the defaults
|
187 |
+
F.opts = $.extend(true, {}, F.defaults, opts);
|
188 |
+
|
189 |
+
//All options are merged recursive except keys
|
190 |
+
if ($.isPlainObject(opts) && opts.keys !== undefined) {
|
191 |
+
F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false;
|
192 |
+
}
|
193 |
+
|
194 |
+
F.group = group;
|
195 |
+
|
196 |
+
F._start(F.opts.index || 0);
|
197 |
+
},
|
198 |
+
|
199 |
+
cancel: function () {
|
200 |
+
if (F.coming && false === F.trigger('onCancel')) {
|
201 |
+
return;
|
202 |
+
}
|
203 |
+
|
204 |
+
F.coming = null;
|
205 |
+
|
206 |
+
F.hideLoading();
|
207 |
+
|
208 |
+
if (F.ajaxLoad) {
|
209 |
+
F.ajaxLoad.abort();
|
210 |
+
}
|
211 |
+
|
212 |
+
F.ajaxLoad = null;
|
213 |
+
|
214 |
+
if (F.imgPreload) {
|
215 |
+
F.imgPreload.onload = F.imgPreload.onabort = F.imgPreload.onerror = null;
|
216 |
+
}
|
217 |
+
},
|
218 |
+
|
219 |
+
close: function (a) {
|
220 |
+
F.cancel();
|
221 |
+
|
222 |
+
if (!F.current || false === F.trigger('beforeClose')) {
|
223 |
+
return;
|
224 |
+
}
|
225 |
+
|
226 |
+
F.unbindEvents();
|
227 |
+
|
228 |
+
//If forced or is still opening then remove immediately
|
229 |
+
if (!F.isOpen || (a && a[0] === true)) {
|
230 |
+
$(".fancybox-wrap").stop().trigger('onReset').remove();
|
231 |
+
|
232 |
+
F._afterZoomOut();
|
233 |
+
|
234 |
+
} else {
|
235 |
+
F.isOpen = F.isOpened = false;
|
236 |
+
|
237 |
+
$(".fancybox-item, .fancybox-nav").remove();
|
238 |
+
|
239 |
+
F.wrap.stop(true).removeClass('fancybox-opened');
|
240 |
+
F.inner.css('overflow', 'hidden');
|
241 |
+
|
242 |
+
F.transitions[F.current.closeMethod]();
|
243 |
+
}
|
244 |
+
},
|
245 |
+
|
246 |
+
// Start/stop slideshow
|
247 |
+
play: function (a) {
|
248 |
+
var clear = function () {
|
249 |
+
clearTimeout(F.player.timer);
|
250 |
+
},
|
251 |
+
set = function () {
|
252 |
+
clear();
|
253 |
+
|
254 |
+
if (F.current && F.player.isActive) {
|
255 |
+
F.player.timer = setTimeout(F.next, F.current.playSpeed);
|
256 |
+
}
|
257 |
+
},
|
258 |
+
stop = function () {
|
259 |
+
clear();
|
260 |
+
|
261 |
+
$('body').unbind('.player');
|
262 |
+
|
263 |
+
F.player.isActive = false;
|
264 |
+
|
265 |
+
F.trigger('onPlayEnd');
|
266 |
+
},
|
267 |
+
start = function () {
|
268 |
+
if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
|
269 |
+
F.player.isActive = true;
|
270 |
+
|
271 |
+
$('body').bind({
|
272 |
+
'afterShow.player onUpdate.player': set,
|
273 |
+
'onCancel.player beforeClose.player': stop,
|
274 |
+
'beforeLoad.player': clear
|
275 |
+
});
|
276 |
+
|
277 |
+
set();
|
278 |
+
|
279 |
+
F.trigger('onPlayStart');
|
280 |
+
}
|
281 |
+
};
|
282 |
+
|
283 |
+
if (F.player.isActive || (a && a[0] === false)) {
|
284 |
+
stop();
|
285 |
+
} else {
|
286 |
+
start();
|
287 |
+
}
|
288 |
+
},
|
289 |
+
|
290 |
+
next: function () {
|
291 |
+
if (F.current) {
|
292 |
+
F.jumpto(F.current.index + 1);
|
293 |
+
}
|
294 |
+
},
|
295 |
+
|
296 |
+
prev: function () {
|
297 |
+
if (F.current) {
|
298 |
+
F.jumpto(F.current.index - 1);
|
299 |
+
}
|
300 |
+
},
|
301 |
+
|
302 |
+
jumpto: function (index) {
|
303 |
+
if (!F.current) {
|
304 |
+
return;
|
305 |
+
}
|
306 |
+
|
307 |
+
index = parseInt(index, 10);
|
308 |
+
|
309 |
+
if (F.group.length > 1 && F.current.loop) {
|
310 |
+
if (index >= F.group.length) {
|
311 |
+
index = 0;
|
312 |
+
|
313 |
+
} else if (index < 0) {
|
314 |
+
index = F.group.length - 1;
|
315 |
+
}
|
316 |
+
}
|
317 |
+
|
318 |
+
if (F.group[index] !== undefined) {
|
319 |
+
F.cancel();
|
320 |
+
|
321 |
+
F._start(index);
|
322 |
+
}
|
323 |
+
},
|
324 |
+
|
325 |
+
reposition: function (absolute, e) {
|
326 |
+
if (F.isOpen) {
|
327 |
+
if (e && e.type === 'scroll') {
|
328 |
+
F.wrap.stop().animate(F._getPosition(absolute), 200);
|
329 |
+
} else {
|
330 |
+
F.wrap.css(F._getPosition(absolute));
|
331 |
+
}
|
332 |
+
}
|
333 |
+
},
|
334 |
+
|
335 |
+
update: function (e) {
|
336 |
+
if (F.isOpen) {
|
337 |
+
// It's a very bad idea to attach handlers to the window scroll event, run this code after a delay
|
338 |
+
if (!didResize) {
|
339 |
+
resizeTimer = setTimeout(function () {
|
340 |
+
var current = F.current;
|
341 |
+
|
342 |
+
if (didResize) {
|
343 |
+
didResize = false;
|
344 |
+
|
345 |
+
if (current) {
|
346 |
+
if (!e || (e && (e.type === 'orientationchange' || (current.autoResize && e.type === 'resize')))) {
|
347 |
+
if (current.autoSize && current.type !== 'iframe') {
|
348 |
+
F.inner.height('auto');
|
349 |
+
current.height = F.inner.height();
|
350 |
+
}
|
351 |
+
|
352 |
+
F._setDimension();
|
353 |
+
|
354 |
+
if (current.canGrow && current.type !== 'iframe') {
|
355 |
+
F.inner.height('auto');
|
356 |
+
}
|
357 |
+
}
|
358 |
+
|
359 |
+
if (current.autoCenter) {
|
360 |
+
F.reposition(null, e);
|
361 |
+
}
|
362 |
+
|
363 |
+
F.trigger('onUpdate');
|
364 |
+
}
|
365 |
+
}
|
366 |
+
}, 100);
|
367 |
+
}
|
368 |
+
|
369 |
+
didResize = true;
|
370 |
+
}
|
371 |
+
},
|
372 |
+
|
373 |
+
toggle: function () {
|
374 |
+
if (F.isOpen) {
|
375 |
+
F.current.fitToView = !F.current.fitToView;
|
376 |
+
|
377 |
+
F.update();
|
378 |
+
}
|
379 |
+
},
|
380 |
+
|
381 |
+
hideLoading: function () {
|
382 |
+
D.unbind('keypress.fb');
|
383 |
+
|
384 |
+
$("#fancybox-loading").remove();
|
385 |
+
},
|
386 |
+
|
387 |
+
showLoading: function () {
|
388 |
+
F.hideLoading();
|
389 |
+
|
390 |
+
//If user will press the escape-button, the request will be canceled
|
391 |
+
D.bind('keypress.fb', function(e) {
|
392 |
+
if (e.keyCode === 27) {
|
393 |
+
e.preventDefault();
|
394 |
+
F.cancel();
|
395 |
+
}
|
396 |
+
});
|
397 |
+
|
398 |
+
$('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body');
|
399 |
+
},
|
400 |
+
|
401 |
+
getViewport: function () {
|
402 |
+
return {
|
403 |
+
x: W.scrollLeft(),
|
404 |
+
y: W.scrollTop(),
|
405 |
+
w: window.innerWidth ? window.innerWidth : W.width(),
|
406 |
+
h: window.innerHeight ? window.innerHeight : W.height()
|
407 |
+
};
|
408 |
+
},
|
409 |
+
|
410 |
+
// Unbind the keyboard / clicking actions
|
411 |
+
unbindEvents: function () {
|
412 |
+
if (F.wrap) {
|
413 |
+
F.wrap.unbind('.fb');
|
414 |
+
}
|
415 |
+
|
416 |
+
D.unbind('.fb');
|
417 |
+
W.unbind('.fb');
|
418 |
+
},
|
419 |
+
|
420 |
+
bindEvents: function () {
|
421 |
+
var current = F.current,
|
422 |
+
keys = current.keys;
|
423 |
+
|
424 |
+
if (!current) {
|
425 |
+
return;
|
426 |
+
}
|
427 |
+
|
428 |
+
W.bind('resize.fb, orientationchange.fb', F.update);
|
429 |
+
|
430 |
+
if (!current.fixed && current.autoCenter) {
|
431 |
+
W.bind("scroll.fb", F.update);
|
432 |
+
}
|
433 |
+
|
434 |
+
if (keys) {
|
435 |
+
D.bind('keydown.fb', function (e) {
|
436 |
+
var code;
|
437 |
+
|
438 |
+
// Ignore key combinations and key events within form elements
|
439 |
+
if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && $.inArray(e.target.tagName.toLowerCase(), ['input', 'textarea', 'select', 'button']) < 0 && !$(e.target).is('[contenteditable]')) {
|
440 |
+
code = e.keyCode;
|
441 |
+
|
442 |
+
if ($.inArray(code, keys.close) > -1) {
|
443 |
+
F.close();
|
444 |
+
e.preventDefault();
|
445 |
+
|
446 |
+
} else if ($.inArray(code, keys.next) > -1) {
|
447 |
+
F.next();
|
448 |
+
e.preventDefault();
|
449 |
+
|
450 |
+
} else if ($.inArray(code, keys.prev) > -1) {
|
451 |
+
F.prev();
|
452 |
+
e.preventDefault();
|
453 |
+
}
|
454 |
+
}
|
455 |
+
});
|
456 |
+
}
|
457 |
+
|
458 |
+
if ($.fn.mousewheel && current.mouseWheel && F.group.length > 1) {
|
459 |
+
F.wrap.bind('mousewheel.fb', function (e, delta) {
|
460 |
+
var target = e.target || null;
|
461 |
+
|
462 |
+
if (delta !== 0 && (!target || target.clientHeight === 0 || (target.scrollHeight === target.clientHeight && target.scrollWidth === target.clientWidth))) {
|
463 |
+
e.preventDefault();
|
464 |
+
|
465 |
+
F[delta > 0 ? 'prev' : 'next']();
|
466 |
+
}
|
467 |
+
});
|
468 |
+
}
|
469 |
+
},
|
470 |
+
|
471 |
+
trigger: function (event) {
|
472 |
+
var ret, obj = F[ $.inArray(event, ['onCancel', 'beforeLoad', 'afterLoad']) > -1 ? 'coming' : 'current' ];
|
473 |
+
|
474 |
+
if (!obj) {
|
475 |
+
return;
|
476 |
+
}
|
477 |
+
|
478 |
+
if ($.isFunction( obj[event] )) {
|
479 |
+
ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1));
|
480 |
+
}
|
481 |
+
|
482 |
+
if (ret === false) {
|
483 |
+
return false;
|
484 |
+
}
|
485 |
+
|
486 |
+
if (obj.helpers) {
|
487 |
+
$.each(obj.helpers, function (helper, opts) {
|
488 |
+
if (opts && $.isPlainObject(F.helpers[helper]) && $.isFunction(F.helpers[helper][event])) {
|
489 |
+
F.helpers[helper][event](opts, obj);
|
490 |
+
}
|
491 |
+
});
|
492 |
+
}
|
493 |
+
|
494 |
+
$.event.trigger(event + '.fb');
|
495 |
+
},
|
496 |
+
|
497 |
+
isImage: function (str) {
|
498 |
+
return isString(str) && str.match(/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i);
|
499 |
+
},
|
500 |
+
|
501 |
+
isSWF: function (str) {
|
502 |
+
return isString(str) && str.match(/\.(swf)(.*)?$/i);
|
503 |
+
},
|
504 |
+
|
505 |
+
_start: function (index) {
|
506 |
+
var coming = {},
|
507 |
+
element = F.group[index] || null,
|
508 |
+
isDom,
|
509 |
+
href,
|
510 |
+
type,
|
511 |
+
rez,
|
512 |
+
hrefParts;
|
513 |
+
|
514 |
+
if (element && (element.nodeType || element instanceof $)) {
|
515 |
+
isDom = true;
|
516 |
+
|
517 |
+
if ($.metadata) {
|
518 |
+
coming = $(element).metadata();
|
519 |
+
}
|
520 |
+
}
|
521 |
+
|
522 |
+
coming = $.extend(true, {}, F.opts, {index : index, element : element}, ($.isPlainObject(element) ? element : coming));
|
523 |
+
|
524 |
+
// Re-check overridable options
|
525 |
+
$.each(['href', 'title', 'content', 'type'], function(i,v) {
|
526 |
+
coming[v] = F.opts[ v ] || (isDom && $(element).attr( v )) || coming[ v ] || null;
|
527 |
+
});
|
528 |
+
|
529 |
+
// Convert margin property to array - top, right, bottom, left
|
530 |
+
if (typeof coming.margin === 'number') {
|
531 |
+
coming.margin = [coming.margin, coming.margin, coming.margin, coming.margin];
|
532 |
+
}
|
533 |
+
|
534 |
+
// 'modal' propery is just a shortcut
|
535 |
+
if (coming.modal) {
|
536 |
+
$.extend(true, coming, {
|
537 |
+
closeBtn : false,
|
538 |
+
closeClick: false,
|
539 |
+
nextClick : false,
|
540 |
+
arrows : false,
|
541 |
+
mouseWheel : false,
|
542 |
+
keys : null,
|
543 |
+
helpers: {
|
544 |
+
overlay : {
|
545 |
+
css: {
|
546 |
+
cursor : 'auto'
|
547 |
+
},
|
548 |
+
closeClick : false
|
549 |
+
}
|
550 |
+
}
|
551 |
+
});
|
552 |
+
}
|
553 |
+
|
554 |
+
//Give a chance for callback or helpers to update coming item (type, title, etc)
|
555 |
+
F.coming = coming;
|
556 |
+
|
557 |
+
if (false === F.trigger('beforeLoad')) {
|
558 |
+
F.coming = null;
|
559 |
+
return;
|
560 |
+
}
|
561 |
+
|
562 |
+
type = coming.type;
|
563 |
+
href = coming.href || element;
|
564 |
+
|
565 |
+
///Check if content type is set, if not, try to get
|
566 |
+
if (!type) {
|
567 |
+
if (isDom) {
|
568 |
+
rez = $(element).data('fancybox-type');
|
569 |
+
|
570 |
+
if (!rez && element.className) {
|
571 |
+
rez = element.className.match(/fancybox\.(\w+)/);
|
572 |
+
type = rez ? rez[1] : null;
|
573 |
+
}
|
574 |
+
}
|
575 |
+
|
576 |
+
if (!type && isString(href)) {
|
577 |
+
if (F.isImage(href)) {
|
578 |
+
type = 'image';
|
579 |
+
|
580 |
+
} else if (F.isSWF(href)) {
|
581 |
+
type = 'swf';
|
582 |
+
|
583 |
+
} else if (href.match(/^#/)) {
|
584 |
+
type = 'inline';
|
585 |
+
}
|
586 |
+
}
|
587 |
+
|
588 |
+
// ...if not - display element itself
|
589 |
+
if (!type) {
|
590 |
+
type = isDom ? 'inline' : 'html';
|
591 |
+
}
|
592 |
+
|
593 |
+
coming.type = type;
|
594 |
+
}
|
595 |
+
|
596 |
+
// Check before try to load; 'inline' and 'html' types need content, others - href
|
597 |
+
if (type === 'inline' || type === 'html') {
|
598 |
+
if (!coming.content) {
|
599 |
+
if (type === 'inline') {
|
600 |
+
coming.content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7
|
601 |
+
|
602 |
+
} else {
|
603 |
+
coming.content = element;
|
604 |
+
}
|
605 |
+
}
|
606 |
+
|
607 |
+
if (!coming.content || !coming.content.length) {
|
608 |
+
type = null;
|
609 |
+
}
|
610 |
+
|
611 |
+
} else if (!href) {
|
612 |
+
type = null;
|
613 |
+
}
|
614 |
+
|
615 |
+
/*
|
616 |
+
* Add reference to the group, so it`s possible to access from callbacks, example:
|
617 |
+
* afterLoad : function() {
|
618 |
+
* this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
|
619 |
+
* }
|
620 |
+
*/
|
621 |
+
|
622 |
+
if (type === 'ajax' && isString(href)) {
|
623 |
+
hrefParts = href.split(/\s+/, 2);
|
624 |
+
|
625 |
+
href = hrefParts.shift();
|
626 |
+
coming.selector = hrefParts.shift();
|
627 |
+
}
|
628 |
+
|
629 |
+
coming.href = href;
|
630 |
+
coming.group = F.group;
|
631 |
+
coming.isDom = isDom;
|
632 |
+
|
633 |
+
if (type === 'image') {
|
634 |
+
F._loadImage();
|
635 |
+
|
636 |
+
} else if (type === 'ajax') {
|
637 |
+
F._loadAjax();
|
638 |
+
|
639 |
+
} else if (type) {
|
640 |
+
F._afterLoad();
|
641 |
+
|
642 |
+
} else {
|
643 |
+
F._error( 'type' );
|
644 |
+
}
|
645 |
+
},
|
646 |
+
|
647 |
+
_error: function ( type ) {
|
648 |
+
F.hideLoading();
|
649 |
+
|
650 |
+
$.extend(F.coming, {
|
651 |
+
type : 'html',
|
652 |
+
autoSize : true,
|
653 |
+
minHeight : 0,
|
654 |
+
hasError : type,
|
655 |
+
content : F.coming.tpl.error
|
656 |
+
});
|
657 |
+
|
658 |
+
F._afterLoad();
|
659 |
+
},
|
660 |
+
|
661 |
+
_loadImage: function () {
|
662 |
+
// Reset preload image so it is later possible to check "complete" property
|
663 |
+
var img = F.imgPreload = new Image();
|
664 |
+
|
665 |
+
img.onload = function () {
|
666 |
+
this.onload = this.onerror = null;
|
667 |
+
|
668 |
+
F.coming.width = this.width;
|
669 |
+
F.coming.height = this.height;
|
670 |
+
|
671 |
+
F._afterLoad();
|
672 |
+
};
|
673 |
+
|
674 |
+
img.onerror = function () {
|
675 |
+
this.onload = this.onerror = null;
|
676 |
+
|
677 |
+
F._error( 'image' );
|
678 |
+
};
|
679 |
+
|
680 |
+
img.src = F.coming.href;
|
681 |
+
|
682 |
+
if (!img.width) {
|
683 |
+
F.showLoading();
|
684 |
+
}
|
685 |
+
},
|
686 |
+
|
687 |
+
_loadAjax: function () {
|
688 |
+
F.showLoading();
|
689 |
+
|
690 |
+
F.ajaxLoad = $.ajax($.extend({}, F.coming.ajax, {
|
691 |
+
url: F.coming.href,
|
692 |
+
error: function (jqXHR, textStatus) {
|
693 |
+
if (F.coming && textStatus !== 'abort') {
|
694 |
+
F._error( 'ajax', jqXHR );
|
695 |
+
|
696 |
+
} else {
|
697 |
+
F.hideLoading();
|
698 |
+
}
|
699 |
+
},
|
700 |
+
success: function (data, textStatus) {
|
701 |
+
if (textStatus === 'success') {
|
702 |
+
F.coming.content = data;
|
703 |
+
|
704 |
+
F._afterLoad();
|
705 |
+
}
|
706 |
+
}
|
707 |
+
}));
|
708 |
+
},
|
709 |
+
|
710 |
+
_preloadImages: function() {
|
711 |
+
var group = F.group,
|
712 |
+
current = F.current,
|
713 |
+
len = group.length,
|
714 |
+
item,
|
715 |
+
href,
|
716 |
+
i,
|
717 |
+
cnt = Math.min(current.preload, len - 1);
|
718 |
+
|
719 |
+
if (!current.preload || group.length < 2) {
|
720 |
+
return;
|
721 |
+
}
|
722 |
+
|
723 |
+
for (i = 1; i <= cnt; i += 1) {
|
724 |
+
item = group[ (current.index + i ) % len ];
|
725 |
+
href = $( item ).attr('href') || item;
|
726 |
+
|
727 |
+
if (item.type === 'image' || F.isImage(href)) {
|
728 |
+
new Image().src = href;
|
729 |
+
}
|
730 |
+
}
|
731 |
+
},
|
732 |
+
|
733 |
+
_afterLoad: function () {
|
734 |
+
F.hideLoading();
|
735 |
+
|
736 |
+
if (!F.coming || false === F.trigger('afterLoad', F.current)) {
|
737 |
+
F.coming = false;
|
738 |
+
|
739 |
+
return;
|
740 |
+
}
|
741 |
+
|
742 |
+
if (F.isOpened) {
|
743 |
+
$(".fancybox-item").remove();
|
744 |
+
|
745 |
+
F.wrap.stop(true).removeClass('fancybox-opened');
|
746 |
+
F.inner.css('overflow', 'hidden');
|
747 |
+
|
748 |
+
F.transitions[F.current.prevMethod]();
|
749 |
+
|
750 |
+
} else {
|
751 |
+
$(".fancybox-wrap").stop().trigger('onReset').remove();
|
752 |
+
|
753 |
+
F.trigger('afterClose');
|
754 |
+
}
|
755 |
+
|
756 |
+
F.unbindEvents();
|
757 |
+
|
758 |
+
F.isOpen = false;
|
759 |
+
F.current = F.coming;
|
760 |
+
|
761 |
+
//Build the neccessary markup
|
762 |
+
F.wrap = $(F.current.tpl.wrap).addClass('fancybox-' + (isMobile ? 'mobile' : 'desktop') + ' fancybox-type-' + F.current.type + ' fancybox-tmp ' + F.current.wrapCSS).appendTo('body');
|
763 |
+
F.outer = $('.fancybox-outer', F.wrap).css('padding', F.current.padding + 'px');
|
764 |
+
F.inner = $('.fancybox-inner', F.wrap);
|
765 |
+
|
766 |
+
F._setContent();
|
767 |
+
},
|
768 |
+
|
769 |
+
_setContent: function () {
|
770 |
+
var current = F.current,
|
771 |
+
content = current.content,
|
772 |
+
type = current.type,
|
773 |
+
loadingBay,
|
774 |
+
minWidth = current.minWidth,
|
775 |
+
minHeight = current.minHeight,
|
776 |
+
maxWidth = current.maxWidth,
|
777 |
+
maxHeight = current.maxHeight;
|
778 |
+
|
779 |
+
switch (type) {
|
780 |
+
case 'inline':
|
781 |
+
case 'ajax':
|
782 |
+
case 'html':
|
783 |
+
if (current.selector) {
|
784 |
+
content = $('<div>').html(content).find(current.selector);
|
785 |
+
|
786 |
+
} else if (content instanceof $) {
|
787 |
+
if (content.parent().hasClass('fancybox-inner')) {
|
788 |
+
content.parents('.fancybox-wrap').unbind('onReset');
|
789 |
+
}
|
790 |
+
|
791 |
+
content = content.show().detach();
|
792 |
+
|
793 |
+
$(F.wrap).bind('onReset', function () {
|
794 |
+
content.appendTo('body').hide();
|
795 |
+
});
|
796 |
+
}
|
797 |
+
|
798 |
+
if (current.autoSize) {
|
799 |
+
loadingBay = $('<div class="fancybox-wrap ' + F.current.wrapCSS + ' fancybox-tmp"></div>')
|
800 |
+
.appendTo('body')
|
801 |
+
.css({
|
802 |
+
minWidth : isPercentage(minWidth) ? minWidth : minWidth + 'px',
|
803 |
+
minHeight : isPercentage(minHeight) ? minHeight : minHeight + 'px',
|
804 |
+
maxWidth : isPercentage(maxWidth) ? maxWidth : maxWidth + 'px',
|
805 |
+
maxHeight : isPercentage(maxHeight) ? maxHeight : maxHeight + 'px'
|
806 |
+
})
|
807 |
+
.append(content);
|
808 |
+
|
809 |
+
current.width = loadingBay.width();
|
810 |
+
current.height = loadingBay.height();
|
811 |
+
|
812 |
+
// Re-check to fix 1px bug in some browsers
|
813 |
+
loadingBay.width( F.current.width );
|
814 |
+
|
815 |
+
if (loadingBay.height() > current.height) {
|
816 |
+
loadingBay.width(current.width + 1);
|
817 |
+
|
818 |
+
current.width = loadingBay.width();
|
819 |
+
current.height = loadingBay.height();
|
820 |
+
}
|
821 |
+
|
822 |
+
content = loadingBay.contents().detach();
|
823 |
+
|
824 |
+
loadingBay.remove();
|
825 |
+
}
|
826 |
+
|
827 |
+
break;
|
828 |
+
|
829 |
+
case 'image':
|
830 |
+
content = current.tpl.image.replace('{href}', current.href);
|
831 |
+
|
832 |
+
current.aspectRatio = true;
|
833 |
+
break;
|
834 |
+
|
835 |
+
case 'swf':
|
836 |
+
content = current.tpl.swf.replace(/\{width\}/g, current.width).replace(/\{height\}/g, current.height).replace(/\{href\}/g, current.href);
|
837 |
+
break;
|
838 |
+
|
839 |
+
case 'iframe':
|
840 |
+
content = $(current.tpl.iframe.replace('{rnd}', new Date().getTime()) )
|
841 |
+
.attr('scrolling', current.scrolling)
|
842 |
+
.attr('src', current.href);
|
843 |
+
|
844 |
+
current.scrolling = isMobile ? 'scroll' : 'auto';
|
845 |
+
|
846 |
+
break;
|
847 |
+
}
|
848 |
+
|
849 |
+
if (type === 'image' || type === 'swf') {
|
850 |
+
current.autoSize = false;
|
851 |
+
current.scrolling = 'visible';
|
852 |
+
}
|
853 |
+
|
854 |
+
if (type === 'iframe' && current.autoSize) {
|
855 |
+
F.showLoading();
|
856 |
+
|
857 |
+
F.inner
|
858 |
+
.width(current.width)
|
859 |
+
.height(current.height)
|
860 |
+
.css('overflow', current.scrolling);
|
861 |
+
|
862 |
+
content.bind({
|
863 |
+
onCancel : function() {
|
864 |
+
$(this).unbind();
|
865 |
+
|
866 |
+
F._afterZoomOut();
|
867 |
+
},
|
868 |
+
load : function() {
|
869 |
+
F.hideLoading();
|
870 |
+
|
871 |
+
try {
|
872 |
+
if (this.contentWindow.document.location) {
|
873 |
+
F.current.height = $(this).contents().find('body').height();
|
874 |
+
}
|
875 |
+
} catch (e) {
|
876 |
+
F.current.autoSize = false;
|
877 |
+
}
|
878 |
+
|
879 |
+
if (F.isOpened) {
|
880 |
+
F.update();
|
881 |
+
|
882 |
+
} else {
|
883 |
+
F._beforeShow();
|
884 |
+
}
|
885 |
+
}
|
886 |
+
}).appendTo(F.inner);
|
887 |
+
|
888 |
+
} else {
|
889 |
+
F.inner.append(content);
|
890 |
+
|
891 |
+
F._beforeShow();
|
892 |
+
}
|
893 |
+
},
|
894 |
+
|
895 |
+
_beforeShow : function() {
|
896 |
+
F.coming = null;
|
897 |
+
|
898 |
+
//Give a chance for helpers or callbacks to update elements
|
899 |
+
F.trigger('beforeShow');
|
900 |
+
|
901 |
+
//Set initial dimensions and hide
|
902 |
+
F._setDimension();
|
903 |
+
F.wrap.hide().removeClass('fancybox-tmp');
|
904 |
+
|
905 |
+
F.bindEvents();
|
906 |
+
|
907 |
+
F._preloadImages();
|
908 |
+
|
909 |
+
F.transitions[ F.isOpened ? F.current.nextMethod : F.current.openMethod ]();
|
910 |
+
},
|
911 |
+
|
912 |
+
_setDimension: function () {
|
913 |
+
var wrap = F.wrap,
|
914 |
+
outer = F.outer,
|
915 |
+
inner = F.inner,
|
916 |
+
current = F.current,
|
917 |
+
viewport = F.getViewport(),
|
918 |
+
margin = current.margin,
|
919 |
+
padding2 = current.padding * 2,
|
920 |
+
width = current.width,
|
921 |
+
height = current.height,
|
922 |
+
maxWidth = current.maxWidth + padding2,
|
923 |
+
maxHeight = current.maxHeight + padding2,
|
924 |
+
minWidth = current.minWidth + padding2,
|
925 |
+
minHeight = current.minHeight + padding2,
|
926 |
+
ratio,
|
927 |
+
height_,
|
928 |
+
space;
|
929 |
+
|
930 |
+
viewport.w -= (margin[1] + margin[3]);
|
931 |
+
viewport.h -= (margin[0] + margin[2]);
|
932 |
+
|
933 |
+
if (isPercentage(width)) {
|
934 |
+
width = (((viewport.w - padding2) * parseFloat(width)) / 100);
|
935 |
+
}
|
936 |
+
|
937 |
+
if (isPercentage(height)) {
|
938 |
+
height = (((viewport.h - padding2) * parseFloat(height)) / 100);
|
939 |
+
}
|
940 |
+
|
941 |
+
ratio = width / height;
|
942 |
+
width += padding2;
|
943 |
+
height += padding2;
|
944 |
+
|
945 |
+
if (current.fitToView) {
|
946 |
+
maxWidth = Math.min(viewport.w, maxWidth);
|
947 |
+
maxHeight = Math.min(viewport.h, maxHeight);
|
948 |
+
}
|
949 |
+
|
950 |
+
if (current.aspectRatio) {
|
951 |
+
if (width > maxWidth) {
|
952 |
+
width = maxWidth;
|
953 |
+
height = ((width - padding2) / ratio) + padding2;
|
954 |
+
}
|
955 |
+
|
956 |
+
if (height > maxHeight) {
|
957 |
+
height = maxHeight;
|
958 |
+
width = ((height - padding2) * ratio) + padding2;
|
959 |
+
}
|
960 |
+
|
961 |
+
if (width < minWidth) {
|
962 |
+
width = minWidth;
|
963 |
+
height = ((width - padding2) / ratio) + padding2;
|
964 |
+
}
|
965 |
+
|
966 |
+
if (height < minHeight) {
|
967 |
+
height = minHeight;
|
968 |
+
width = ((height - padding2) * ratio) + padding2;
|
969 |
+
}
|
970 |
+
|
971 |
+
} else {
|
972 |
+
width = Math.max(minWidth, Math.min(width, maxWidth));
|
973 |
+
height = Math.max(minHeight, Math.min(height, maxHeight));
|
974 |
+
}
|
975 |
+
|
976 |
+
width = Math.round(width);
|
977 |
+
height = Math.round(height);
|
978 |
+
|
979 |
+
//Reset dimensions
|
980 |
+
$(wrap.add(outer).add(inner)).width('auto').height('auto');
|
981 |
+
|
982 |
+
inner.width(width - padding2).height(height - padding2);
|
983 |
+
wrap.width(width);
|
984 |
+
|
985 |
+
height_ = wrap.height(); // Real wrap height
|
986 |
+
|
987 |
+
//Fit wrapper inside
|
988 |
+
if (width > maxWidth || height_ > maxHeight) {
|
989 |
+
while ((width > maxWidth || height_ > maxHeight) && width > minWidth && height_ > minHeight) {
|
990 |
+
height = height - 10;
|
991 |
+
|
992 |
+
if (current.aspectRatio) {
|
993 |
+
width = Math.round(((height - padding2) * ratio) + padding2);
|
994 |
+
|
995 |
+
if (width < minWidth) {
|
996 |
+
width = minWidth;
|
997 |
+
height = ((width - padding2) / ratio) + padding2;
|
998 |
+
}
|
999 |
+
|
1000 |
+
} else {
|
1001 |
+
width = width - 10;
|
1002 |
+
}
|
1003 |
+
|
1004 |
+
inner.width(width - padding2).height(height - padding2);
|
1005 |
+
wrap.width(width);
|
1006 |
+
|
1007 |
+
height_ = wrap.height();
|
1008 |
+
}
|
1009 |
+
}
|
1010 |
+
|
1011 |
+
current.dim = {
|
1012 |
+
width: width,
|
1013 |
+
height: height_
|
1014 |
+
};
|
1015 |
+
|
1016 |
+
current.canGrow = current.autoSize && height > minHeight && height < maxHeight;
|
1017 |
+
current.canShrink = false;
|
1018 |
+
current.canExpand = false;
|
1019 |
+
|
1020 |
+
if ((width - padding2) < current.width || (height - padding2) < current.height) {
|
1021 |
+
current.canExpand = true;
|
1022 |
+
|
1023 |
+
} else if ((width > viewport.w || height_ > viewport.h) && width > minWidth && height > minHeight) {
|
1024 |
+
current.canShrink = true;
|
1025 |
+
}
|
1026 |
+
|
1027 |
+
space = height_ - padding2;
|
1028 |
+
|
1029 |
+
F.innerSpace = space - inner.height();
|
1030 |
+
F.outerSpace = space - outer.height();
|
1031 |
+
},
|
1032 |
+
|
1033 |
+
_getPosition: function (a) {
|
1034 |
+
var current = F.current,
|
1035 |
+
viewport = F.getViewport(),
|
1036 |
+
margin = current.margin,
|
1037 |
+
width = F.wrap.width() + margin[1] + margin[3],
|
1038 |
+
height = F.wrap.height() + margin[0] + margin[2],
|
1039 |
+
rez = {
|
1040 |
+
position: 'absolute',
|
1041 |
+
top: margin[0] + viewport.y,
|
1042 |
+
left: margin[3] + viewport.x
|
1043 |
+
};
|
1044 |
+
|
1045 |
+
if (current.autoCenter && current.fixed && (!a || a[0] === false) && height <= viewport.h && width <= viewport.w) {
|
1046 |
+
rez = {
|
1047 |
+
position: 'fixed',
|
1048 |
+
top: margin[0],
|
1049 |
+
left: margin[3]
|
1050 |
+
};
|
1051 |
+
}
|
1052 |
+
|
1053 |
+
rez.top = Math.ceil(Math.max(rez.top, rez.top + ((viewport.h - height) * current.topRatio))) + 'px';
|
1054 |
+
rez.left = Math.ceil(Math.max(rez.left, rez.left + ((viewport.w - width) * 0.5))) + 'px';
|
1055 |
+
|
1056 |
+
return rez;
|
1057 |
+
},
|
1058 |
+
|
1059 |
+
_afterZoomIn: function () {
|
1060 |
+
var current = F.current, scrolling = current ? current.scrolling : 'no';
|
1061 |
+
|
1062 |
+
if (!current) {
|
1063 |
+
return;
|
1064 |
+
}
|
1065 |
+
|
1066 |
+
F.isOpen = F.isOpened = true;
|
1067 |
+
|
1068 |
+
F.wrap.addClass('fancybox-opened').css('overflow', 'visible');
|
1069 |
+
|
1070 |
+
F.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));
|
1071 |
+
|
1072 |
+
//Assign a click event
|
1073 |
+
if (current.closeClick || current.nextClick) {
|
1074 |
+
//This is not the perfect solution but arrows have to be next to content so their height will match
|
1075 |
+
// and I do not want another wrapper around content
|
1076 |
+
F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {
|
1077 |
+
if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {
|
1078 |
+
F[ current.closeClick ? 'close' : 'next' ]();
|
1079 |
+
}
|
1080 |
+
});
|
1081 |
+
}
|
1082 |
+
|
1083 |
+
//Create a close button
|
1084 |
+
if (current.closeBtn) {
|
1085 |
+
$(current.tpl.closeBtn).appendTo(F.outer).bind('click.fb', F.close);
|
1086 |
+
}
|
1087 |
+
|
1088 |
+
//Create navigation arrows
|
1089 |
+
if (current.arrows && F.group.length > 1) {
|
1090 |
+
if (current.loop || current.index > 0) {
|
1091 |
+
$(current.tpl.prev).appendTo(F.inner).bind('click.fb', F.prev);
|
1092 |
+
}
|
1093 |
+
|
1094 |
+
if (current.loop || current.index < F.group.length - 1) {
|
1095 |
+
$(current.tpl.next).appendTo(F.inner).bind('click.fb', F.next);
|
1096 |
+
}
|
1097 |
+
}
|
1098 |
+
|
1099 |
+
F.trigger('afterShow');
|
1100 |
+
|
1101 |
+
F.update();
|
1102 |
+
|
1103 |
+
if (F.opts.autoPlay && !F.player.isActive) {
|
1104 |
+
F.opts.autoPlay = false;
|
1105 |
+
|
1106 |
+
F.play();
|
1107 |
+
}
|
1108 |
+
},
|
1109 |
+
|
1110 |
+
_afterZoomOut: function () {
|
1111 |
+
F.trigger('afterClose');
|
1112 |
+
|
1113 |
+
F.wrap.trigger('onReset').remove();
|
1114 |
+
|
1115 |
+
$.extend(F, {
|
1116 |
+
group: {},
|
1117 |
+
opts: {},
|
1118 |
+
current: null,
|
1119 |
+
isActive: false,
|
1120 |
+
isOpened: false,
|
1121 |
+
isOpen: false,
|
1122 |
+
wrap: null,
|
1123 |
+
outer: null,
|
1124 |
+
inner: null
|
1125 |
+
});
|
1126 |
+
}
|
1127 |
+
});
|
1128 |
+
|
1129 |
+
/*
|
1130 |
+
* Default transitions
|
1131 |
+
*/
|
1132 |
+
|
1133 |
+
F.transitions = {
|
1134 |
+
getOrigPosition: function () {
|
1135 |
+
var current = F.current,
|
1136 |
+
element = current.element,
|
1137 |
+
padding = current.padding,
|
1138 |
+
orig = $(current.orig),
|
1139 |
+
pos = {},
|
1140 |
+
width = 50,
|
1141 |
+
height = 50,
|
1142 |
+
viewport;
|
1143 |
+
|
1144 |
+
if (!orig.length && current.isDom && $(element).is(':visible')) {
|
1145 |
+
orig = $(element).find('img:first');
|
1146 |
+
|
1147 |
+
if (!orig.length) {
|
1148 |
+
orig = $(element);
|
1149 |
+
}
|
1150 |
+
}
|
1151 |
+
|
1152 |
+
if (orig.length) {
|
1153 |
+
pos = orig.offset();
|
1154 |
+
|
1155 |
+
if (orig.is('img')) {
|
1156 |
+
width = orig.outerWidth();
|
1157 |
+
height = orig.outerHeight();
|
1158 |
+
}
|
1159 |
+
|
1160 |
+
} else {
|
1161 |
+
viewport = F.getViewport();
|
1162 |
+
|
1163 |
+
pos.top = viewport.y + (viewport.h - height) * 0.5;
|
1164 |
+
pos.left = viewport.x + (viewport.w - width) * 0.5;
|
1165 |
+
}
|
1166 |
+
|
1167 |
+
pos = {
|
1168 |
+
top: Math.ceil(pos.top - padding) + 'px',
|
1169 |
+
left: Math.ceil(pos.left - padding) + 'px',
|
1170 |
+
width: Math.ceil(width + padding * 2) + 'px',
|
1171 |
+
height: Math.ceil(height + padding * 2) + 'px'
|
1172 |
+
};
|
1173 |
+
|
1174 |
+
return pos;
|
1175 |
+
},
|
1176 |
+
|
1177 |
+
step: function (now, fx) {
|
1178 |
+
var ratio, innerValue, outerValue;
|
1179 |
+
|
1180 |
+
if (fx.prop === 'width' || fx.prop === 'height') {
|
1181 |
+
innerValue = outerValue = Math.ceil(now - (F.current.padding * 2));
|
1182 |
+
|
1183 |
+
if (fx.prop === 'height') {
|
1184 |
+
ratio = (now - fx.start) / (fx.end - fx.start);
|
1185 |
+
|
1186 |
+
if (fx.start > fx.end) {
|
1187 |
+
ratio = 1 - ratio;
|
1188 |
+
}
|
1189 |
+
|
1190 |
+
innerValue -= F.innerSpace * ratio;
|
1191 |
+
outerValue -= F.outerSpace * ratio;
|
1192 |
+
}
|
1193 |
+
|
1194 |
+
F.inner[fx.prop](innerValue);
|
1195 |
+
F.outer[fx.prop](outerValue);
|
1196 |
+
}
|
1197 |
+
},
|
1198 |
+
|
1199 |
+
zoomIn: function () {
|
1200 |
+
var wrap = F.wrap,
|
1201 |
+
current = F.current,
|
1202 |
+
effect = current.openEffect,
|
1203 |
+
elastic = effect === 'elastic',
|
1204 |
+
dim = current.dim,
|
1205 |
+
startPos = $.extend({}, dim, F._getPosition( elastic )),
|
1206 |
+
endPos = $.extend({opacity : 1}, startPos);
|
1207 |
+
|
1208 |
+
//Remove "position" property that breaks older IE
|
1209 |
+
delete endPos.position;
|
1210 |
+
|
1211 |
+
if (elastic) {
|
1212 |
+
startPos = this.getOrigPosition();
|
1213 |
+
|
1214 |
+
if (current.openOpacity) {
|
1215 |
+
startPos.opacity = 0;
|
1216 |
+
}
|
1217 |
+
|
1218 |
+
F.outer.add(F.inner).width('auto').height('auto');
|
1219 |
+
} else if (effect === 'fade') {
|
1220 |
+
startPos.opacity = 0;
|
1221 |
+
}
|
1222 |
+
|
1223 |
+
wrap.css(startPos)
|
1224 |
+
.show()
|
1225 |
+
.animate(endPos, {
|
1226 |
+
duration : effect === 'none' ? 0 : current.openSpeed,
|
1227 |
+
easing : current.openEasing,
|
1228 |
+
step: elastic ? this.step : null,
|
1229 |
+
complete: F._afterZoomIn
|
1230 |
+
});
|
1231 |
+
},
|
1232 |
+
|
1233 |
+
zoomOut: function () {
|
1234 |
+
var wrap = F.wrap,
|
1235 |
+
current = F.current,
|
1236 |
+
effect = current.openEffect,
|
1237 |
+
elastic = effect === 'elastic',
|
1238 |
+
endPos = {opacity : 0};
|
1239 |
+
|
1240 |
+
if (elastic) {
|
1241 |
+
if (wrap.css('position') === 'fixed') {
|
1242 |
+
wrap.css(F._getPosition(true));
|
1243 |
+
}
|
1244 |
+
|
1245 |
+
endPos = this.getOrigPosition();
|
1246 |
+
|
1247 |
+
if (current.closeOpacity) {
|
1248 |
+
endPos.opacity = 0;
|
1249 |
+
}
|
1250 |
+
}
|
1251 |
+
|
1252 |
+
wrap.animate(endPos, {
|
1253 |
+
duration: effect === 'none' ? 0 : current.closeSpeed,
|
1254 |
+
easing: current.closeEasing,
|
1255 |
+
step: elastic ? this.step : null,
|
1256 |
+
complete: F._afterZoomOut
|
1257 |
+
});
|
1258 |
+
},
|
1259 |
+
|
1260 |
+
changeIn: function () {
|
1261 |
+
var wrap = F.wrap,
|
1262 |
+
current = F.current,
|
1263 |
+
effect = current.nextEffect,
|
1264 |
+
startPos = F._getPosition( effect === 'elastic' ),
|
1265 |
+
endPos = { opacity : 1 };
|
1266 |
+
|
1267 |
+
if (effect === 'elastic') {
|
1268 |
+
startPos.top = (parseInt(startPos.top, 10) - 200) + 'px';
|
1269 |
+
endPos.top = '+=200px';
|
1270 |
+
startPos.opacity = 0;
|
1271 |
+
}
|
1272 |
+
|
1273 |
+
wrap.css(startPos)
|
1274 |
+
.show()
|
1275 |
+
.animate(endPos, {
|
1276 |
+
duration : effect === 'none' ? 0 : current.nextSpeed,
|
1277 |
+
easing : current.nextEasing,
|
1278 |
+
complete: function() {
|
1279 |
+
//Somehow this helps to restore overflow
|
1280 |
+
setTimeout( F._afterZoomIn, 1);
|
1281 |
+
}
|
1282 |
+
});
|
1283 |
+
},
|
1284 |
+
|
1285 |
+
changeOut: function () {
|
1286 |
+
var wrap = F.wrap,
|
1287 |
+
current = F.current,
|
1288 |
+
effect = current.nextEffect,
|
1289 |
+
endPos = { opacity : 0 },
|
1290 |
+
cleanUp = function () {
|
1291 |
+
$(this).trigger('onReset').remove();
|
1292 |
+
};
|
1293 |
+
|
1294 |
+
wrap.removeClass('fancybox-opened');
|
1295 |
+
|
1296 |
+
if (effect === 'elastic') {
|
1297 |
+
endPos.top = '+=200px';
|
1298 |
+
}
|
1299 |
+
|
1300 |
+
wrap.animate(endPos, {
|
1301 |
+
duration: effect === 'none' ? 0 : current.prevSpeed,
|
1302 |
+
easing: current.prevEasing,
|
1303 |
+
complete: cleanUp
|
1304 |
+
});
|
1305 |
+
}
|
1306 |
+
};
|
1307 |
+
|
1308 |
+
/*
|
1309 |
+
* Overlay helper
|
1310 |
+
*/
|
1311 |
+
|
1312 |
+
F.helpers.overlay = {
|
1313 |
+
overlay: null,
|
1314 |
+
|
1315 |
+
update: function () {
|
1316 |
+
var width, scrollWidth, offsetWidth;
|
1317 |
+
|
1318 |
+
if (!isMobile) {
|
1319 |
+
//Reset width/height so it will not mess
|
1320 |
+
this.overlay.width(0).height(0);
|
1321 |
+
}
|
1322 |
+
|
1323 |
+
if ($.browser.msie) {
|
1324 |
+
scrollWidth = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth);
|
1325 |
+
offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
|
1326 |
+
|
1327 |
+
width = scrollWidth < offsetWidth ? W.width() : scrollWidth;
|
1328 |
+
|
1329 |
+
} else {
|
1330 |
+
width = D.width();
|
1331 |
+
}
|
1332 |
+
|
1333 |
+
this.overlay.width(width).height(D.height());
|
1334 |
+
},
|
1335 |
+
|
1336 |
+
beforeShow: function (opts) {
|
1337 |
+
if (this.overlay) {
|
1338 |
+
return;
|
1339 |
+
}
|
1340 |
+
|
1341 |
+
opts = $.extend(true, {
|
1342 |
+
speedIn : 'fast',
|
1343 |
+
closeClick : true,
|
1344 |
+
opacity : 1,
|
1345 |
+
css : {
|
1346 |
+
background: 'black'
|
1347 |
+
}
|
1348 |
+
}, opts);
|
1349 |
+
|
1350 |
+
this.overlay = $('<div id="fancybox-overlay"></div>').css(opts.css).appendTo('body');
|
1351 |
+
|
1352 |
+
this.update();
|
1353 |
+
|
1354 |
+
if (opts.closeClick) {
|
1355 |
+
this.overlay.bind('click.fb', F.close);
|
1356 |
+
}
|
1357 |
+
|
1358 |
+
W.bind("resize.fb", $.proxy(this.update, this));
|
1359 |
+
|
1360 |
+
this.overlay.fadeTo(opts.speedIn, opts.opacity);
|
1361 |
+
},
|
1362 |
+
|
1363 |
+
onUpdate: function () {
|
1364 |
+
//Update as content may change document dimensions
|
1365 |
+
this.update();
|
1366 |
+
},
|
1367 |
+
|
1368 |
+
afterClose: function (opts) {
|
1369 |
+
if (this.overlay) {
|
1370 |
+
this.overlay.fadeOut(opts.speedOut || 0, function () {
|
1371 |
+
$(this).remove();
|
1372 |
+
});
|
1373 |
+
}
|
1374 |
+
|
1375 |
+
this.overlay = null;
|
1376 |
+
}
|
1377 |
+
};
|
1378 |
+
|
1379 |
+
/*
|
1380 |
+
* Title helper
|
1381 |
+
*/
|
1382 |
+
|
1383 |
+
F.helpers.title = {
|
1384 |
+
beforeShow: function (opts) {
|
1385 |
+
var title, text = F.current.title;
|
1386 |
+
|
1387 |
+
if (text) {
|
1388 |
+
title = $('<div class="fancybox-title fancybox-title-' + opts.type + '-wrap">' + text + '</div>').appendTo('body');
|
1389 |
+
|
1390 |
+
if (opts.type === 'float') {
|
1391 |
+
//This helps for some browsers
|
1392 |
+
title.width(title.width());
|
1393 |
+
|
1394 |
+
title.wrapInner('<span class="child"></span>');
|
1395 |
+
|
1396 |
+
//Increase bottom margin so this title will also fit into viewport
|
1397 |
+
F.current.margin[2] += Math.abs(parseInt(title.css('margin-bottom'), 10));
|
1398 |
+
}
|
1399 |
+
|
1400 |
+
title.appendTo(opts.type === 'over' ? F.inner : (opts.type === 'outside' ? F.wrap : F.outer));
|
1401 |
+
}
|
1402 |
+
}
|
1403 |
+
};
|
1404 |
+
|
1405 |
+
// jQuery plugin initialization
|
1406 |
+
$.fn.fancybox = function (options) {
|
1407 |
+
var that = $(this),
|
1408 |
+
selector = this.selector || '',
|
1409 |
+
index,
|
1410 |
+
run = function(e) {
|
1411 |
+
var what = this, idx = index, relType, relVal;
|
1412 |
+
|
1413 |
+
if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey)) {
|
1414 |
+
e.preventDefault();
|
1415 |
+
|
1416 |
+
relType = options.groupAttr || 'data-fancybox-group';
|
1417 |
+
relVal = $(what).attr(relType);
|
1418 |
+
|
1419 |
+
if (!relVal) {
|
1420 |
+
relType = 'rel';
|
1421 |
+
relVal = what[ relType ];
|
1422 |
+
}
|
1423 |
+
|
1424 |
+
if (relVal && relVal !== '' && relVal !== 'nofollow') {
|
1425 |
+
what = selector.length ? $(selector) : that;
|
1426 |
+
what = what.filter('[' + relType + '="' + relVal + '"]');
|
1427 |
+
idx = what.index(this);
|
1428 |
+
}
|
1429 |
+
|
1430 |
+
options.index = idx;
|
1431 |
+
|
1432 |
+
F.open(what, options);
|
1433 |
+
}
|
1434 |
+
};
|
1435 |
+
|
1436 |
+
options = options || {};
|
1437 |
+
index = options.index || 0;
|
1438 |
+
|
1439 |
+
if (selector) {
|
1440 |
+
D.undelegate(selector, 'click.fb-start').delegate(selector, 'click.fb-start', run);
|
1441 |
+
|
1442 |
+
} else {
|
1443 |
+
that.unbind('click.fb-start').bind('click.fb-start', run);
|
1444 |
+
}
|
1445 |
+
|
1446 |
+
return this;
|
1447 |
+
};
|
1448 |
+
|
1449 |
+
}(window, document));
|
assets/fancyBox/source/jquery.fancybox.pack.js
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*! fancyBox v2.0.5 fancyapps.com | fancyapps.com/fancybox/#license */
|
2 |
+
(function(n,q,v){var d=n.jQuery,l=d(n),m=d(q),a=d.fancybox=function(){a.open.apply(this,arguments)},u=!1,r=q.createTouch!==v,s=function(a){return"string"===d.type(a)},t=function(a){return s(a)&&-1<a.indexOf("%")};d.extend(a,{version:"2.0.5",defaults:{padding:15,margin:20,width:800,height:600,minWidth:100,minHeight:100,maxWidth:9999,maxHeight:9999,autoSize:!0,autoResize:!r,autoCenter:!r,fitToView:!0,aspectRatio:!1,topRatio:0.5,fixed:!(d.browser.msie&&6>=d.browser.version)&&!r,scrolling:"auto",wrapCSS:"fancybox-default",
|
3 |
+
arrows:!0,closeBtn:!0,closeClick:!1,nextClick:!1,mouseWheel:!0,autoPlay:!1,playSpeed:3E3,preload:3,modal:!1,loop:!0,ajax:{dataType:"html",headers:{"X-fancyBox":!0}},keys:{next:[13,32,34,39,40],prev:[8,33,37,38],close:[27]},tpl:{wrap:'<div class="fancybox-wrap"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div>',image:'<img class="fancybox-image" src="{href}" alt="" />',iframe:'<iframe class="fancybox-iframe" name="fancybox-frame{rnd}" frameborder="0" hspace="0"'+(d.browser.msie?
|
4 |
+
' allowtransparency="true"':"")+"></iframe>",swf:'<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="wmode" value="transparent" /><param name="allowfullscreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="movie" value="{href}" /><embed src="{href}" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="100%" height="100%" wmode="transparent"></embed></object>',error:'<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
|
5 |
+
closeBtn:'<div title="Close" class="fancybox-item fancybox-close"></div>',next:'<a title="Next" class="fancybox-nav fancybox-next"><span></span></a>',prev:'<a title="Previous" class="fancybox-nav fancybox-prev"><span></span></a>'},openEffect:"fade",openSpeed:250,openEasing:"swing",openOpacity:!0,openMethod:"zoomIn",closeEffect:"fade",closeSpeed:250,closeEasing:"swing",closeOpacity:!0,closeMethod:"zoomOut",nextEffect:"elastic",nextSpeed:300,nextEasing:"swing",nextMethod:"changeIn",prevEffect:"elastic",
|
6 |
+
prevSpeed:300,prevEasing:"swing",prevMethod:"changeOut",helpers:{overlay:{speedIn:0,speedOut:300,opacity:0.8,css:{cursor:"pointer"},closeClick:!0},title:{type:"float"}}},group:{},opts:{},coming:null,current:null,isOpen:!1,isOpened:!1,wrap:null,outer:null,inner:null,player:{timer:null,isActive:!1},ajaxLoad:null,imgPreload:null,transitions:{},helpers:{},open:function(b,c){a.close(!0);b&&!d.isArray(b)&&(b=b instanceof d?d(b).get():[b]);a.isActive=!0;a.opts=d.extend(!0,{},a.defaults,c);d.isPlainObject(c)&&
|
7 |
+
c.keys!==v&&(a.opts.keys=c.keys?d.extend({},a.defaults.keys,c.keys):!1);a.group=b;a._start(a.opts.index||0)},cancel:function(){a.coming&&!1===a.trigger("onCancel")||(a.coming=null,a.hideLoading(),a.ajaxLoad&&a.ajaxLoad.abort(),a.ajaxLoad=null,a.imgPreload&&(a.imgPreload.onload=a.imgPreload.onabort=a.imgPreload.onerror=null))},close:function(b){a.cancel();a.current&&!1!==a.trigger("beforeClose")&&(a.unbindEvents(),!a.isOpen||b&&!0===b[0]?(d(".fancybox-wrap").stop().trigger("onReset").remove(),a._afterZoomOut()):
|
8 |
+
(a.isOpen=a.isOpened=!1,d(".fancybox-item, .fancybox-nav").remove(),a.wrap.stop(!0).removeClass("fancybox-opened"),a.inner.css("overflow","hidden"),a.transitions[a.current.closeMethod]()))},play:function(b){var c=function(){clearTimeout(a.player.timer)},g=function(){c();a.current&&a.player.isActive&&(a.player.timer=setTimeout(a.next,a.current.playSpeed))},e=function(){c();d("body").unbind(".player");a.player.isActive=!1;a.trigger("onPlayEnd")};if(a.player.isActive||b&&!1===b[0])e();else if(a.current&&
|
9 |
+
(a.current.loop||a.current.index<a.group.length-1))a.player.isActive=!0,d("body").bind({"afterShow.player onUpdate.player":g,"onCancel.player beforeClose.player":e,"beforeLoad.player":c}),g(),a.trigger("onPlayStart")},next:function(){a.current&&a.jumpto(a.current.index+1)},prev:function(){a.current&&a.jumpto(a.current.index-1)},jumpto:function(b){a.current&&(b=parseInt(b,10),1<a.group.length&&a.current.loop&&(b>=a.group.length?b=0:0>b&&(b=a.group.length-1)),a.group[b]!==v&&(a.cancel(),a._start(b)))},
|
10 |
+
reposition:function(b,c){a.isOpen&&(c&&"scroll"===c.type?a.wrap.stop().animate(a._getPosition(b),200):a.wrap.css(a._getPosition(b)))},update:function(b){a.isOpen&&(u||setTimeout(function(){var c=a.current;if(u&&(u=!1,c)){if(!b||b&&("orientationchange"===b.type||c.autoResize&&"resize"===b.type))c.autoSize&&"iframe"!==c.type&&(a.inner.height("auto"),c.height=a.inner.height()),a._setDimension(),c.canGrow&&"iframe"!==c.type&&a.inner.height("auto");c.autoCenter&&a.reposition(null,b);a.trigger("onUpdate")}},
|
11 |
+
100),u=!0)},toggle:function(){a.isOpen&&(a.current.fitToView=!a.current.fitToView,a.update())},hideLoading:function(){m.unbind("keypress.fb");d("#fancybox-loading").remove()},showLoading:function(){a.hideLoading();m.bind("keypress.fb",function(b){27===b.keyCode&&(b.preventDefault(),a.cancel())});d('<div id="fancybox-loading"><div></div></div>').click(a.cancel).appendTo("body")},getViewport:function(){return{x:l.scrollLeft(),y:l.scrollTop(),w:n.innerWidth?n.innerWidth:l.width(),h:n.innerHeight?n.innerHeight:
|
12 |
+
l.height()}},unbindEvents:function(){a.wrap&&a.wrap.unbind(".fb");m.unbind(".fb");l.unbind(".fb")},bindEvents:function(){var b=a.current,c=b.keys;b&&(l.bind("resize.fb, orientationchange.fb",a.update),!b.fixed&&b.autoCenter&&l.bind("scroll.fb",a.update),c&&m.bind("keydown.fb",function(b){var e;!b.ctrlKey&&!b.altKey&&!b.shiftKey&&!b.metaKey&&0>d.inArray(b.target.tagName.toLowerCase(),["input","textarea","select","button"])&&!d(b.target).is("[contenteditable]")&&(e=b.keyCode,-1<d.inArray(e,c.close)?
|
13 |
+
(a.close(),b.preventDefault()):-1<d.inArray(e,c.next)?(a.next(),b.preventDefault()):-1<d.inArray(e,c.prev)&&(a.prev(),b.preventDefault()))}),d.fn.mousewheel&&b.mouseWheel&&1<a.group.length&&a.wrap.bind("mousewheel.fb",function(b,c){var d=b.target||null;if(0!==c&&(!d||0===d.clientHeight||d.scrollHeight===d.clientHeight&&d.scrollWidth===d.clientWidth))b.preventDefault(),a[0<c?"prev":"next"]()}))},trigger:function(b){var c,g=a[-1<d.inArray(b,["onCancel","beforeLoad","afterLoad"])?"coming":"current"];
|
14 |
+
if(g){d.isFunction(g[b])&&(c=g[b].apply(g,Array.prototype.slice.call(arguments,1)));if(!1===c)return!1;g.helpers&&d.each(g.helpers,function(c,f){if(f&&d.isPlainObject(a.helpers[c])&&d.isFunction(a.helpers[c][b]))a.helpers[c][b](f,g)});d.event.trigger(b+".fb")}},isImage:function(a){return s(a)&&a.match(/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i)},isSWF:function(a){return s(a)&&a.match(/\.(swf)(.*)?$/i)},_start:function(b){var c={},g=a.group[b]||null,e,f,i;if(g&&(g.nodeType||g instanceof d))e=!0,d.metadata&&
|
15 |
+
(c=d(g).metadata());c=d.extend(!0,{},a.opts,{index:b,element:g},d.isPlainObject(g)?g:c);d.each(["href","title","content","type"],function(b,f){c[f]=a.opts[f]||e&&d(g).attr(f)||c[f]||null});"number"===typeof c.margin&&(c.margin=[c.margin,c.margin,c.margin,c.margin]);c.modal&&d.extend(!0,c,{closeBtn:!1,closeClick:!1,nextClick:!1,arrows:!1,mouseWheel:!1,keys:null,helpers:{overlay:{css:{cursor:"auto"},closeClick:!1}}});a.coming=c;if(!1===a.trigger("beforeLoad"))a.coming=null;else{f=c.type;b=c.href||g;
|
16 |
+
f||(e&&(i=d(g).data("fancybox-type"),!i&&g.className&&(f=(i=g.className.match(/fancybox\.(\w+)/))?i[1]:null)),!f&&s(b)&&(a.isImage(b)?f="image":a.isSWF(b)?f="swf":b.match(/^#/)&&(f="inline")),f||(f=e?"inline":"html"),c.type=f);if("inline"===f||"html"===f){if(c.content||(c.content="inline"===f?d(s(b)?b.replace(/.*(?=#[^\s]+$)/,""):b):g),!c.content||!c.content.length)f=null}else b||(f=null);"ajax"===f&&s(b)&&(i=b.split(/\s+/,2),b=i.shift(),c.selector=i.shift());c.href=b;c.group=a.group;c.isDom=e;"image"===
|
17 |
+
f?a._loadImage():"ajax"===f?a._loadAjax():f?a._afterLoad():a._error("type")}},_error:function(b){a.hideLoading();d.extend(a.coming,{type:"html",autoSize:!0,minHeight:0,hasError:b,content:a.coming.tpl.error});a._afterLoad()},_loadImage:function(){var b=a.imgPreload=new Image;b.onload=function(){this.onload=this.onerror=null;a.coming.width=this.width;a.coming.height=this.height;a._afterLoad()};b.onerror=function(){this.onload=this.onerror=null;a._error("image")};b.src=a.coming.href;b.width||a.showLoading()},
|
18 |
+
_loadAjax:function(){a.showLoading();a.ajaxLoad=d.ajax(d.extend({},a.coming.ajax,{url:a.coming.href,error:function(b,c){a.coming&&"abort"!==c?a._error("ajax",b):a.hideLoading()},success:function(b,c){"success"===c&&(a.coming.content=b,a._afterLoad())}}))},_preloadImages:function(){var b=a.group,c=a.current,g=b.length,e,f,i,h=Math.min(c.preload,g-1);if(c.preload&&!(2>b.length))for(i=1;i<=h;i+=1)if(e=b[(c.index+i)%g],f=d(e).attr("href")||e,"image"===e.type||a.isImage(f))(new Image).src=f},_afterLoad:function(){a.hideLoading();
|
19 |
+
!a.coming||!1===a.trigger("afterLoad",a.current)?a.coming=!1:(a.isOpened?(d(".fancybox-item").remove(),a.wrap.stop(!0).removeClass("fancybox-opened"),a.inner.css("overflow","hidden"),a.transitions[a.current.prevMethod]()):(d(".fancybox-wrap").stop().trigger("onReset").remove(),a.trigger("afterClose")),a.unbindEvents(),a.isOpen=!1,a.current=a.coming,a.wrap=d(a.current.tpl.wrap).addClass("fancybox-"+(r?"mobile":"desktop")+" fancybox-type-"+a.current.type+" fancybox-tmp "+a.current.wrapCSS).appendTo("body"),
|
20 |
+
a.outer=d(".fancybox-outer",a.wrap).css("padding",a.current.padding+"px"),a.inner=d(".fancybox-inner",a.wrap),a._setContent())},_setContent:function(){var b=a.current,c=b.content,g=b.type,e;e=b.minWidth;var f=b.minHeight,i=b.maxWidth,h=b.maxHeight;switch(g){case "inline":case "ajax":case "html":b.selector?c=d("<div>").html(c).find(b.selector):c instanceof d&&(c.parent().hasClass("fancybox-inner")&&c.parents(".fancybox-wrap").unbind("onReset"),c=c.show().detach(),d(a.wrap).bind("onReset",function(){c.appendTo("body").hide()}));
|
21 |
+
b.autoSize&&(e=d('<div class="fancybox-wrap '+a.current.wrapCSS+' fancybox-tmp"></div>').appendTo("body").css({minWidth:t(e)?e:e+"px",minHeight:t(f)?f:f+"px",maxWidth:t(i)?i:i+"px",maxHeight:t(h)?h:h+"px"}).append(c),b.width=e.width(),b.height=e.height(),e.width(a.current.width),e.height()>b.height&&(e.width(b.width+1),b.width=e.width(),b.height=e.height()),c=e.contents().detach(),e.remove());break;case "image":c=b.tpl.image.replace("{href}",b.href);b.aspectRatio=!0;break;case "swf":c=b.tpl.swf.replace(/\{width\}/g,
|
22 |
+
b.width).replace(/\{height\}/g,b.height).replace(/\{href\}/g,b.href);break;case "iframe":c=d(b.tpl.iframe.replace("{rnd}",(new Date).getTime())).attr("scrolling",b.scrolling).attr("src",b.href),b.scrolling=r?"scroll":"auto"}if("image"===g||"swf"===g)b.autoSize=!1,b.scrolling="visible";"iframe"===g&&b.autoSize?(a.showLoading(),a.inner.width(b.width).height(b.height).css("overflow",b.scrolling),c.bind({onCancel:function(){d(this).unbind();a._afterZoomOut()},load:function(){a.hideLoading();try{this.contentWindow.document.location&&
|
23 |
+
(a.current.height=d(this).contents().find("body").height())}catch(b){a.current.autoSize=!1}a.isOpened?a.update():a._beforeShow()}}).appendTo(a.inner)):(a.inner.append(c),a._beforeShow())},_beforeShow:function(){a.coming=null;a.trigger("beforeShow");a._setDimension();a.wrap.hide().removeClass("fancybox-tmp");a.bindEvents();a._preloadImages();a.transitions[a.isOpened?a.current.nextMethod:a.current.openMethod]()},_setDimension:function(){var b=a.wrap,c=a.outer,g=a.inner,e=a.current,f=a.getViewport(),
|
24 |
+
i=e.margin,h=2*e.padding,j=e.width,k=e.height,l=e.maxWidth+h,o=e.maxHeight+h,m=e.minWidth+h,n=e.minHeight+h,p;f.w-=i[1]+i[3];f.h-=i[0]+i[2];t(j)&&(j=(f.w-h)*parseFloat(j)/100);t(k)&&(k=(f.h-h)*parseFloat(k)/100);i=j/k;j+=h;k+=h;e.fitToView&&(l=Math.min(f.w,l),o=Math.min(f.h,o));if(e.aspectRatio){if(j>l&&(j=l,k=(j-h)/i+h),k>o&&(k=o,j=(k-h)*i+h),j<m&&(j=m,k=(j-h)/i+h),k<n)k=n,j=(k-h)*i+h}else j=Math.max(m,Math.min(j,l)),k=Math.max(n,Math.min(k,o));j=Math.round(j);k=Math.round(k);d(b.add(c).add(g)).width("auto").height("auto");
|
25 |
+
g.width(j-h).height(k-h);b.width(j);p=b.height();if(j>l||p>o)for(;(j>l||p>o)&&j>m&&p>n;)k-=10,e.aspectRatio?(j=Math.round((k-h)*i+h),j<m&&(j=m,k=(j-h)/i+h)):j-=10,g.width(j-h).height(k-h),b.width(j),p=b.height();e.dim={width:j,height:p};e.canGrow=e.autoSize&&k>n&&k<o;e.canShrink=!1;e.canExpand=!1;if(j-h<e.width||k-h<e.height)e.canExpand=!0;else if((j>f.w||p>f.h)&&j>m&&k>n)e.canShrink=!0;b=p-h;a.innerSpace=b-g.height();a.outerSpace=b-c.height()},_getPosition:function(b){var c=a.current,d=a.getViewport(),
|
26 |
+
e=c.margin,f=a.wrap.width()+e[1]+e[3],i=a.wrap.height()+e[0]+e[2],h={position:"absolute",top:e[0]+d.y,left:e[3]+d.x};if(c.autoCenter&&c.fixed&&(!b||!1===b[0])&&i<=d.h&&f<=d.w)h={position:"fixed",top:e[0],left:e[3]};h.top=Math.ceil(Math.max(h.top,h.top+(d.h-i)*c.topRatio))+"px";h.left=Math.ceil(Math.max(h.left,h.left+0.5*(d.w-f)))+"px";return h},_afterZoomIn:function(){var b=a.current,c=b?b.scrolling:"no";if(b&&(a.isOpen=a.isOpened=!0,a.wrap.addClass("fancybox-opened").css("overflow","visible"),a.inner.css("overflow",
|
27 |
+
"yes"===c?"scroll":"no"===c?"hidden":c),(b.closeClick||b.nextClick)&&a.inner.css("cursor","pointer").bind("click.fb",function(c){if(!d(c.target).is("a")&&!d(c.target).parent().is("a"))a[b.closeClick?"close":"next"]()}),b.closeBtn&&d(b.tpl.closeBtn).appendTo(a.outer).bind("click.fb",a.close),b.arrows&&1<a.group.length&&((b.loop||0<b.index)&&d(b.tpl.prev).appendTo(a.inner).bind("click.fb",a.prev),(b.loop||b.index<a.group.length-1)&&d(b.tpl.next).appendTo(a.inner).bind("click.fb",a.next)),a.trigger("afterShow"),
|
28 |
+
a.update(),a.opts.autoPlay&&!a.player.isActive))a.opts.autoPlay=!1,a.play()},_afterZoomOut:function(){a.trigger("afterClose");a.wrap.trigger("onReset").remove();d.extend(a,{group:{},opts:{},current:null,isActive:!1,isOpened:!1,isOpen:!1,wrap:null,outer:null,inner:null})}});a.transitions={getOrigPosition:function(){var b=a.current,c=b.element,g=b.padding,e=d(b.orig),f={},i=50,h=50;!e.length&&b.isDom&&d(c).is(":visible")&&(e=d(c).find("img:first"),e.length||(e=d(c)));e.length?(f=e.offset(),e.is("img")&&
|
29 |
+
(i=e.outerWidth(),h=e.outerHeight())):(b=a.getViewport(),f.top=b.y+0.5*(b.h-h),f.left=b.x+0.5*(b.w-i));return f={top:Math.ceil(f.top-g)+"px",left:Math.ceil(f.left-g)+"px",width:Math.ceil(i+2*g)+"px",height:Math.ceil(h+2*g)+"px"}},step:function(b,c){var d,e,f;if("width"===c.prop||"height"===c.prop)e=f=Math.ceil(b-2*a.current.padding),"height"===c.prop&&(d=(b-c.start)/(c.end-c.start),c.start>c.end&&(d=1-d),e-=a.innerSpace*d,f-=a.outerSpace*d),a.inner[c.prop](e),a.outer[c.prop](f)},zoomIn:function(){var b=
|
30 |
+
a.wrap,c=a.current,g=c.openEffect,e="elastic"===g,f=d.extend({},c.dim,a._getPosition(e)),i=d.extend({opacity:1},f);delete i.position;e?(f=this.getOrigPosition(),c.openOpacity&&(f.opacity=0),a.outer.add(a.inner).width("auto").height("auto")):"fade"===g&&(f.opacity=0);b.css(f).show().animate(i,{duration:"none"===g?0:c.openSpeed,easing:c.openEasing,step:e?this.step:null,complete:a._afterZoomIn})},zoomOut:function(){var b=a.wrap,c=a.current,d=c.openEffect,e="elastic"===d,f={opacity:0};e&&("fixed"===b.css("position")&&
|
31 |
+
b.css(a._getPosition(!0)),f=this.getOrigPosition(),c.closeOpacity&&(f.opacity=0));b.animate(f,{duration:"none"===d?0:c.closeSpeed,easing:c.closeEasing,step:e?this.step:null,complete:a._afterZoomOut})},changeIn:function(){var b=a.wrap,c=a.current,d=c.nextEffect,e=a._getPosition("elastic"===d),f={opacity:1};"elastic"===d&&(e.top=parseInt(e.top,10)-200+"px",f.top="+=200px",e.opacity=0);b.css(e).show().animate(f,{duration:"none"===d?0:c.nextSpeed,easing:c.nextEasing,complete:function(){setTimeout(a._afterZoomIn,
|
32 |
+
1)}})},changeOut:function(){var b=a.wrap,c=a.current,g=c.nextEffect,e={opacity:0};b.removeClass("fancybox-opened");"elastic"===g&&(e.top="+=200px");b.animate(e,{duration:"none"===g?0:c.prevSpeed,easing:c.prevEasing,complete:function(){d(this).trigger("onReset").remove()}})}};a.helpers.overlay={overlay:null,update:function(){var a,c;r||this.overlay.width(0).height(0);d.browser.msie?(a=Math.max(q.documentElement.scrollWidth,q.body.scrollWidth),c=Math.max(q.documentElement.offsetWidth,q.body.offsetWidth),
|
33 |
+
a=a<c?l.width():a):a=m.width();this.overlay.width(a).height(m.height())},beforeShow:function(b){this.overlay||(b=d.extend(!0,{speedIn:"fast",closeClick:!0,opacity:1,css:{background:"black"}},b),this.overlay=d('<div id="fancybox-overlay"></div>').css(b.css).appendTo("body"),this.update(),b.closeClick&&this.overlay.bind("click.fb",a.close),l.bind("resize.fb",d.proxy(this.update,this)),this.overlay.fadeTo(b.speedIn,b.opacity))},onUpdate:function(){this.update()},afterClose:function(a){this.overlay&&
|
34 |
+
this.overlay.fadeOut(a.speedOut||0,function(){d(this).remove()});this.overlay=null}};a.helpers.title={beforeShow:function(b){var c;if(c=a.current.title)c=d('<div class="fancybox-title fancybox-title-'+b.type+'-wrap">'+c+"</div>").appendTo("body"),"float"===b.type&&(c.width(c.width()),c.wrapInner('<span class="child"></span>'),a.current.margin[2]+=Math.abs(parseInt(c.css("margin-bottom"),10))),c.appendTo("over"===b.type?a.inner:"outside"===b.type?a.wrap:a.outer)}};d.fn.fancybox=function(b){var c=d(this),
|
35 |
+
g=this.selector||"",e,f=function(f){var h=this,j=e,k;!f.ctrlKey&&!f.altKey&&!f.shiftKey&&!f.metaKey&&(f.preventDefault(),f=b.groupAttr||"data-fancybox-group",k=d(h).attr(f),k||(f="rel",k=h[f]),k&&""!==k&&"nofollow"!==k&&(h=g.length?d(g):c,h=h.filter("["+f+'="'+k+'"]'),j=h.index(this)),b.index=j,a.open(h,b))},b=b||{};e=b.index||0;g?m.undelegate(g,"click.fb-start").delegate(g,"click.fb-start",f):c.unbind("click.fb-start").bind("click.fb-start",f);return this}})(window,document);
|
assets/hmbkp.css
CHANGED
@@ -1,9 +1,6 @@
|
|
1 |
-
#icon-backupwordpress.icon32
|
2 |
-
|
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; }
|
@@ -14,10 +11,71 @@ tfoot p { margin: 0; font-weight: normal; }
|
|
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 |
-
|
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 |
.contextual-help-tabs-wrap .updated { margin: 15px 0 0; }
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
#icon-backupwordpress.icon32 { background: url(icon_backupwordpress_32x32.png); }
|
2 |
+
|
|
|
3 |
tfoot p { margin: 0; font-weight: normal; }
|
|
|
|
|
4 |
#hmbkp-constants dl { overflow: hidden; margin: 20px 0; }
|
5 |
#hmbkp-constants dt { float: left; min-width: 250px; clear: both; padding: 6px; margin: 1px 0; cursor: pointer; }
|
6 |
#hmbkp-constants dd { color: #666; padding: 7px 0 7px 250px; border-top: 1px solid #DFDFDF; margin: 0; cursor: pointer; min-height: 40px; }
|
11 |
#hmbkp-constants dt:not(.hmbkp_active):hover + dd, #hmbkp-constants dt:not(.hmbkp_active) + dd:hover { background-color: #FFF; }
|
12 |
#hmbkp-constants dd:hover p, #hmbkp-constants dt:hover + dd p { display: none; }
|
13 |
#hmbkp-constants dd:hover .example, #hmbkp-constants dt:hover + dd .example { display: inline; }
|
14 |
+
|
|
|
15 |
.completed th, .completed td { background-color: #FFFFE0; }
|
16 |
.hmbkp_active:before { content: "\00a0 \2713 "; font-size: 11px; }
|
17 |
.hmbkp_active, .hmbkp_active code, #hmbkp-constants .hmbkp_active + dd { background: #E5F7E8; }
|
18 |
.contextual-help-tabs-wrap .updated { margin: 15px 0 0; }
|
19 |
+
|
20 |
+
.subsubsub { width: 100%; margin: 20px 0px 0px 0px; border-bottom: 1px solid #EEE; }
|
21 |
+
.subsubsub li + li::before { content: "| "; }
|
22 |
+
.subsubsub .add-new-h2 { top: 0; }
|
23 |
+
|
24 |
+
.ui-tabs-nav .ui-tabs-selected a, .ui-tabs-nav .ui-state-active a { font-weight: bold; color: #000; }
|
25 |
+
.hmbkp_schedule { clear: both; overflow: hidden; }
|
26 |
+
|
27 |
+
.fancybox-inner { overflow-x: hidden !important; }
|
28 |
+
.fancybox-inner fieldset { max-width: 100%; }
|
29 |
+
.hmbkp-form fieldset { float: left; }
|
30 |
+
.js .hmbkp-form fieldset + fieldset { display: none; margin-right: -100%; }
|
31 |
+
|
32 |
+
.hmbkp-form label { display: block; line-height: 25px; padding-bottom: 20px; border-bottom: 1px dotted #CCC; margin-bottom: 20px; width: 320px; position: relative; }
|
33 |
+
|
34 |
+
.hmbkp-form legend { padding: 0 0 20px; font-size: 1.17em; font-weight: bold; }
|
35 |
+
.hmbkp-form label > * { float: right; }
|
36 |
+
.hmbkp-form label.hidden { display: none; }
|
37 |
+
.hmbkp-form label > input, .hmbkp-form label > select { min-width: 200px; }
|
38 |
+
.hmbkp-form label .description { line-height: 16px; margin-top: 10px; float: none; }
|
39 |
+
.hmbkp-form p.submit { margin: 20px 0 0; padding: 0; }
|
40 |
+
.hmbkp-form .button-primary { float: right; }
|
41 |
+
.hmbkp-form [type="number"] { min-width: 40px; width: 40px; }
|
42 |
+
.hmbkp-error span { position: absolute; top: -18px; left: 0; color: red; }
|
43 |
+
.hmbkp-error input[type], .hmbkp-error select { border-color: red; }
|
44 |
+
|
45 |
+
.hmbkp-form ul { width: 320px; overflow: hidden; }
|
46 |
+
.hmbkp-form ul.hmbkp_file_list { background-color: #FFF; max-height: 200px; overflow-y: scroll; display: block; border-radius: 4px; box-sizing: border-box; clear: both; box-shadow: inset 0px 0px 2px #CCC; font-size: 11px; }
|
47 |
+
.hmbkp_file_list li { margin: 0; padding: 5px; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; line-height: 16px; }
|
48 |
+
.hmbkp_file_list li + li { border-top: 1px dotted #CCC; }
|
49 |
+
|
50 |
+
.hmbkp-schedule-sentence { margin: 0; font-size: 16px; font-weight: lighter; margin: 30px 0 10px; clear: both; margin-left: 10px; }
|
51 |
+
.hmbkp-schedule-sentence::before { content: "\2714"; margin-right: 10px; width: 16px; height: 47px; display: block; float: left; }
|
52 |
+
.hmbkp-schedule-sentence.hmbkp-running::before { background-image: url('wpspin_light.gif'); background-repeat: no-repeat; margin-right: 10px; content: " "; }
|
53 |
+
.hmbkp-schedule-sentence .hmbkp-status { display: block; font-size: 12px; color: #666; margin: 2px 0 0 26px; }
|
54 |
+
.hmbkp-schedule-sentence [title] { border-bottom: 1px dotted #CCC; cursor: help; }
|
55 |
+
|
56 |
+
.hmbkp-schedule-sentence .hmbkp-schedule-actions { visibility: visible; }
|
57 |
+
.hmbkp-schedule-actions { font-size: 12px; font-weight: normal; margin: 0 0 0 26px; }
|
58 |
+
|
59 |
+
button.hmbkp-ajax-loading { padding-left: 20px; }
|
60 |
+
button.hmbkp-ajax-loading::before { background-image: url('wpspin_light.gif'); background-repeat: no-repeat; background-position: 1px -1px; margin-left: -20px; display: inline-block; width: 16px; height: 16px; content: " "; vertical-align: middle; padding-right: 3px; }
|
61 |
+
|
62 |
+
button { height: 14px; }
|
63 |
+
|
64 |
+
.delete-action { color: #BC0B0B; }
|
65 |
+
.delete-action:hover .delete-action:focus { color: red; }
|
66 |
+
|
67 |
+
label[for="hmbkp-new-exclude-rule"] { overflow: hidden; }
|
68 |
+
.hmbkp_preview_exclude_rule { float: right; margin-top: 1px; }
|
69 |
+
.hmbkp_preview_exclude_rule.hmbkp-ajax-loading { width: 44px; }
|
70 |
+
div.hmbkp_add_exclude_rule { display: block; line-height: 25px; width: 320px; overflow: hidden; }
|
71 |
+
div.hmbkp_add_exclude_rule input { min-width: 240px; float: left; }
|
72 |
+
.hmbkp_preview_exclude_rule { float: right; width: 56px; }
|
73 |
+
.hmbkp_save_exclude_rule, .hmbkp_cancel_save_exclude_rule { float: right; }
|
74 |
+
|
75 |
+
.hmbkp-exclude-preview-open table, .hmbkp-exclude-preview-open .hmbkp-tabs, .hmbkp-exclude-preview-open p.submit { display: none; }
|
76 |
+
.hmbkp-exclude-preview-open .hmbkp_add_exclude_rule { margin: 0; }
|
77 |
+
|
78 |
+
table.widefat tbody td { padding: 8px 7px; }
|
79 |
+
.hmbkp-edit-schedule-excludes-form td a, .hmbkp-edit-schedule-excludes-form td span.reason { float: right; }
|
80 |
+
.hmbkp-edit-schedule-excludes-form td span.reason { color: #CCC; }
|
81 |
+
input[type="datetime-local"] { border-radius: 3px; border-width: 1px; border-style: solid; box-sizing: border-box; border-color: #DFDFDF; background-color: white; }
|
assets/hmbkp.js
CHANGED
@@ -1,70 +1,337 @@
|
|
1 |
jQuery( document ).ready( function( $ ) {
|
2 |
|
3 |
-
|
4 |
-
|
5 |
-
}
|
6 |
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
$( this ).empty().append( data );
|
12 |
-
} ).fadeIn();
|
13 |
-
}
|
14 |
-
);
|
15 |
-
}
|
16 |
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
|
21 |
-
|
22 |
-
|
23 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
24 |
|
25 |
-
|
|
|
|
|
|
|
|
|
|
|
26 |
|
27 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
28 |
|
29 |
-
|
|
|
30 |
|
31 |
-
$( this ).
|
32 |
|
33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
|
35 |
-
|
36 |
|
37 |
-
|
|
|
38 |
|
39 |
-
|
40 |
|
41 |
e.preventDefault();
|
42 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
} );
|
44 |
|
45 |
-
|
|
|
|
|
|
|
|
|
46 |
|
47 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
e.preventDefault();
|
50 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
} );
|
52 |
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
|
57 |
-
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
59 |
}
|
60 |
|
|
|
|
|
61 |
|
62 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
63 |
|
64 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
65 |
|
66 |
-
|
67 |
|
|
|
|
|
|
|
68 |
function( data ) {
|
69 |
|
70 |
if ( data == 0 ) {
|
@@ -73,9 +340,9 @@ function hmbkpRedirectOnBackupComplete() {
|
|
73 |
|
74 |
} else {
|
75 |
|
76 |
-
setTimeout( 'hmbkpRedirectOnBackupComplete();',
|
77 |
|
78 |
-
jQuery( '
|
79 |
|
80 |
}
|
81 |
}
|
1 |
jQuery( document ).ready( function( $ ) {
|
2 |
|
3 |
+
// Don't ever cache ajax requests
|
4 |
+
$.ajaxSetup( { 'cache' : false } );
|
|
|
5 |
|
6 |
+
// Remove the loading class when ajax requests complete
|
7 |
+
$( document ).ajaxComplete( function() {
|
8 |
+
$( '.hmbkp-ajax-loading' ).removeClass( 'hmbkp-ajax-loading' );
|
9 |
+
} );
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
+
// Setup the tabs
|
12 |
+
$( '.hmbkp-tabs' ).tabs();
|
13 |
+
|
14 |
+
// Set the first tab to be active
|
15 |
+
if ( ! $( '.subsubsub a.current' ).size() )
|
16 |
+
$( '.subsubsub li:first a').addClass( 'current' );
|
17 |
+
|
18 |
+
// Initialize fancybox
|
19 |
+
$( '.fancybox' ).fancybox( {
|
20 |
+
|
21 |
+
'modal' : true,
|
22 |
+
'type' : 'ajax',
|
23 |
+
'maxWidth' : 320,
|
24 |
+
'afterShow' : function() {
|
25 |
+
|
26 |
+
$( '.hmbkp-tabs' ).tabs();
|
27 |
+
|
28 |
+
if ( $( '.hmbkp-form p.submit:contains(\'Update\')' ).size() )
|
29 |
+
$( '<button type="button" class="button-secondary hmbkp_cancel">' + objectL10n.cancel + '</button></p>' ).appendTo( '.hmbkp-form p.submit' );
|
30 |
+
|
31 |
+
$( '.hmbkp_cancel' ).click( function() {
|
32 |
+
$.fancybox.close();
|
33 |
+
} );
|
34 |
+
|
35 |
+
}
|
36 |
+
|
37 |
+
} );
|
38 |
+
|
39 |
+
// Show delete confirm message for delete schedule
|
40 |
+
$( document ).on( 'click', '.hmbkp-schedule-actions .delete-action', function( e ) {
|
41 |
+
|
42 |
+
if ( ! confirm( objectL10n.delete_schedule ) )
|
43 |
+
e.preventDefault();
|
44 |
+
|
45 |
+
} );
|
46 |
+
|
47 |
+
// Show delete confirm message for delete backup
|
48 |
+
$( document ).on( 'click', '.hmbkp_manage_backups_row .delete-action', function( e ) {
|
49 |
+
|
50 |
+
if ( ! confirm( objectL10n.delete_backup ) )
|
51 |
+
e.preventDefault();
|
52 |
+
|
53 |
+
} );
|
54 |
+
|
55 |
+
// Show delete confirm message for remove exclude rule
|
56 |
+
$( document ).on( 'click', '.hmbkp-edit-schedule-excludes-form .delete-action', function( e ) {
|
57 |
+
|
58 |
+
if ( ! confirm( objectL10n.remove_exclude_rule ) )
|
59 |
+
e.preventDefault();
|
60 |
+
|
61 |
+
} );
|
62 |
+
|
63 |
+
// Preview exclude rule
|
64 |
+
$( document ).on( 'click', '.hmbkp_preview_exclude_rule', function() {
|
65 |
+
|
66 |
+
if ( ! $( '.hmbkp_add_exclude_rule input' ).val() ) {
|
67 |
+
$( '.hmbkp_add_exclude_rule ul' ).remove();
|
68 |
+
$( '.hmbkp_add_exclude_rule p' ).remove();
|
69 |
+
return;
|
70 |
+
}
|
71 |
+
|
72 |
+
$( this ).addClass( 'hmbkp-ajax-loading' );
|
73 |
+
|
74 |
+
$.post(
|
75 |
+
ajaxurl,
|
76 |
+
{ 'action' : 'hmbkp_file_list', 'hmbkp_schedule_excludes' : $( '.hmbkp_add_exclude_rule input' ).val(), 'hmbkp_schedule_id' : $( '[name="hmbkp_schedule_id"]' ).val(), 'hmbkp_file_method' : 'get_excluded_files' },
|
77 |
+
function( data ) {
|
78 |
+
|
79 |
+
$( '.hmbkp_add_exclude_rule ul' ).remove();
|
80 |
+
$( '.hmbkp_add_exclude_rule p' ).remove();
|
81 |
+
|
82 |
+
if ( data.indexOf( 'hmbkp_file_list' ) != -1 )
|
83 |
+
$( '.hmbkp_add_exclude_rule' ).append( data );
|
84 |
+
|
85 |
+
else
|
86 |
+
$( '.hmbkp_add_exclude_rule' ).append( '<p>There was an error previewing the exclude rule.</p>' );
|
87 |
+
|
88 |
+
$( '.hmbkp-edit-schedule-excludes-form' ).addClass( 'hmbkp-exclude-preview-open' );
|
89 |
+
|
90 |
+
}
|
91 |
+
).error( function() {
|
92 |
+
|
93 |
+
|
94 |
+
|
95 |
+
} );
|
96 |
+
|
97 |
+
} );
|
98 |
+
|
99 |
+
// Fire the preview button when the enter key is pressed in the preview input
|
100 |
+
$( document ).on( 'keypress', '.hmbkp_add_exclude_rule input', function( e ) {
|
101 |
+
|
102 |
+
if ( ! $( '.hmbkp_add_exclude_rule input' ).val() )
|
103 |
+
return true;
|
104 |
+
|
105 |
+
var code = ( e.keyCode ? e.keyCode : e.which );
|
106 |
+
|
107 |
+
if ( code != 13 )
|
108 |
+
return true;
|
109 |
+
|
110 |
+
$( '.hmbkp_preview_exclude_rule' ).click();
|
111 |
+
|
112 |
+
e.preventDefault();
|
113 |
+
|
114 |
+
} );
|
115 |
+
|
116 |
+
// Cancel add exclude rule
|
117 |
+
$( document ).on( 'click', '.hmbkp_cancel_save_exclude_rule, .hmbkp-edit-schedule-excludes-form .submit button', function() {
|
118 |
+
|
119 |
+
$( '.hmbkp_add_exclude_rule ul' ).remove();
|
120 |
+
$( '.hmbkp_add_exclude_rule p' ).remove();
|
121 |
+
|
122 |
+
$( '.hmbkp-edit-schedule-excludes-form' ).removeClass( 'hmbkp-exclude-preview-open' );
|
123 |
+
|
124 |
+
} );
|
125 |
+
|
126 |
+
// Toggle additional fieldsets on
|
127 |
+
$( document ).on( 'click', '.hmbkp-toggle-fieldset', function() {
|
128 |
+
|
129 |
+
// Get the current fieldset
|
130 |
+
var fromFieldset = 'fieldset.' + $( this ).closest( 'fieldset' ).attr( 'class' );
|
131 |
+
var toFieldset = 'fieldset.' + $( this ).attr( 'data-hmbkp-fieldset' );
|
132 |
+
|
133 |
+
// Show the one we are moving too
|
134 |
+
$( toFieldset ).show().find( 'p.submit button' ).data( 'hmbkp-previous-fieldset', fromFieldset );
|
135 |
|
136 |
+
// Animate
|
137 |
+
$( fromFieldset ).animate( {
|
138 |
+
marginLeft : '-100%'
|
139 |
+
}, 'fast', function() {
|
140 |
+
$( this ).hide();
|
141 |
+
} );
|
142 |
|
143 |
+
} );
|
144 |
+
|
145 |
+
// Toggle additional fieldsets off
|
146 |
+
$( document ).on( 'click', '.hmbkp-form fieldset + fieldset p.submit button', function() {
|
147 |
+
|
148 |
+
// Get the current fieldset
|
149 |
+
var fromFieldset = 'fieldset.' + $( this ).closest( 'fieldset' ).attr( 'class' );
|
150 |
+
var toFieldset = $( this ).data( 'hmbkp-previous-fieldset' );
|
151 |
+
|
152 |
+
// Show the one we are moving too
|
153 |
+
$( toFieldset ).show();
|
154 |
+
|
155 |
+
$( toFieldset ).animate( {
|
156 |
+
marginLeft : '0'
|
157 |
+
}, 'fast', function() {
|
158 |
+
$( fromFieldset ).hide();
|
159 |
+
}
|
160 |
+
);
|
161 |
+
|
162 |
+
} );
|
163 |
|
164 |
+
// Add exclude rule
|
165 |
+
$( document ).on( 'click', '.hmbkp_save_exclude_rule', function() {
|
166 |
|
167 |
+
$( this ).addClass( 'hmbkp-ajax-loading' );
|
168 |
|
169 |
+
$.post(
|
170 |
+
ajaxurl,
|
171 |
+
{ 'action' : 'hmbkp_add_exclude_rule', 'hmbkp_exclude_rule' : $( '.hmbkp_add_exclude_rule input' ).val(), 'hmbkp_schedule_id' : $( '[name="hmbkp_schedule_id"]' ).val() },
|
172 |
+
function( data ) {
|
173 |
+
$( '.hmbkp-edit-schedule-excludes-form' ).replaceWith( data );
|
174 |
+
$( '.hmbkp-edit-schedule-excludes-form' ).show();
|
175 |
+
$( '.hmbkp-tabs' ).tabs();
|
176 |
+
}
|
177 |
+
);
|
178 |
|
179 |
+
} );
|
180 |
|
181 |
+
// Remove exclude rule
|
182 |
+
$( document ).on( 'click', '.hmbkp-edit-schedule-excludes-form td a', function( e ) {
|
183 |
|
184 |
+
$( this ).addClass( 'hmbkp-ajax-loading' );
|
185 |
|
186 |
e.preventDefault();
|
187 |
|
188 |
+
$.post(
|
189 |
+
ajaxurl,
|
190 |
+
{ 'action' : 'hmbkp_delete_exclude_rule', 'hmbkp_exclude_rule' : $( this ).closest( 'td' ).attr( 'data-hmbkp-exclude-rule' ), 'hmbkp_schedule_id' : $( '[name="hmbkp_schedule_id"]' ).val() },
|
191 |
+
function( data ) {
|
192 |
+
$( '.hmbkp-edit-schedule-excludes-form' ).replaceWith( data );
|
193 |
+
$( '.hmbkp-edit-schedule-excludes-form' ).show();
|
194 |
+
$( '.hmbkp-tabs' ).tabs();
|
195 |
+
}
|
196 |
+
);
|
197 |
+
|
198 |
} );
|
199 |
|
200 |
+
// Edit schedule form submit
|
201 |
+
$( document ).on( 'submit', 'form.hmbkp-form', function( e ) {
|
202 |
+
|
203 |
+
isNewSchedule = $( this ).closest( 'form' ).attr( 'data-schedule-action' ) == 'add' ? true : false;
|
204 |
+
scheduleId = $( this ).closest( 'form' ).find( '[name="hmbkp_schedule_id"]' ).val();
|
205 |
|
206 |
+
// Warn that backups will be deleted if max backups has been set to less than the number of backups currently stored
|
207 |
+
if ( ! isNewSchedule && Number( $( 'input[name="hmbkp_schedule_max_backups"]' ).val() ) < Number( $( '.hmbkp_manage_backups_row' ).size() ) && ! confirm( objectL10n.remove_old_backups ) )
|
208 |
+
return false;
|
209 |
+
|
210 |
+
$( this ).find( 'button[type="submit"]' ).addClass( 'hmbkp-ajax-loading' );
|
211 |
+
|
212 |
+
$( '.hmbkp-error span' ).remove();
|
213 |
+
$( '.hmbkp-error' ).removeClass( 'hmbkp-error' );
|
214 |
|
215 |
e.preventDefault();
|
216 |
|
217 |
+
$.post(
|
218 |
+
ajaxurl + '?' + $( this ).serialize(),
|
219 |
+
{ 'action' : 'hmnkp_edit_schedule_submit' },
|
220 |
+
function( data ) {
|
221 |
+
|
222 |
+
// Assume success if no data passed back
|
223 |
+
if ( ! data ) {
|
224 |
+
|
225 |
+
$.fancybox.close();
|
226 |
+
|
227 |
+
// Reload the page so we see changes
|
228 |
+
if ( isNewSchedule )
|
229 |
+
location.replace( '//' + location.host + location.pathname + '?page=backupwordpress&hmbkp_schedule_id=' + scheduleId );
|
230 |
+
|
231 |
+
else
|
232 |
+
location.reload( true );
|
233 |
+
|
234 |
+
} else {
|
235 |
+
|
236 |
+
// Get the errors json string
|
237 |
+
errors = JSON.parse( data );
|
238 |
+
|
239 |
+
// Loop through the errors
|
240 |
+
$.each( errors, function( key, value ) {
|
241 |
+
|
242 |
+
// Focus the first field that errored
|
243 |
+
if ( typeof( hmbkp_focused ) == 'undefined' ) {
|
244 |
+
|
245 |
+
$( '[name="' + key + '"]' ).focus();
|
246 |
+
|
247 |
+
hmbkp_focused = true;
|
248 |
+
|
249 |
+
}
|
250 |
+
|
251 |
+
// Add an error class to all fields with errors
|
252 |
+
$( '[name="' + key + '"]' ).closest( 'label' ).addClass( 'hmbkp-error' );
|
253 |
+
|
254 |
+
// Add the error message
|
255 |
+
$( '[name="' + key + '"]' ).after( '<span>' + value + '</span>' );
|
256 |
+
|
257 |
+
} );
|
258 |
+
|
259 |
+
}
|
260 |
+
|
261 |
+
}
|
262 |
+
);
|
263 |
+
|
264 |
} );
|
265 |
|
266 |
+
// Text the cron response using ajax
|
267 |
+
$.get( ajaxurl, { 'action' : 'hmbkp_cron_test' },
|
268 |
+
function( data ) {
|
269 |
+
if ( data != 1 ) {
|
270 |
+
$( '.wrap > h2' ).after( data );
|
271 |
+
}
|
272 |
+
}
|
273 |
+
);
|
274 |
+
|
275 |
+
// Calculate the estimated backup size
|
276 |
+
if ( $( '.hmbkp-schedule-sentence .calculating' ).size() ) {
|
277 |
+
$.get( ajaxurl, { 'action' : 'hmbkp_calculate', 'hmbkp_schedule_id' : $( '[data-hmbkp-schedule-id]' ).attr( 'data-hmbkp-schedule-id' ) },
|
278 |
+
function( data ) {
|
279 |
+
|
280 |
+
if ( data.indexOf( 'title' ) != -1 )
|
281 |
+
$( '.hmbkp-schedule-sentence' ).replaceWith( data );
|
282 |
+
|
283 |
+
// Fail silently for now
|
284 |
+
else
|
285 |
+
$( '.calculating' ).remove();
|
286 |
|
287 |
+
}
|
288 |
+
).error( function() {
|
289 |
+
|
290 |
+
// Fail silently for now
|
291 |
+
$( '.calculating' ).remove();
|
292 |
+
|
293 |
+
} );
|
294 |
}
|
295 |
|
296 |
+
if ( $( '.hmbkp-running' ).size() )
|
297 |
+
hmbkpRedirectOnBackupComplete();
|
298 |
|
299 |
+
$( '.hmbkp-run' ).live( 'click', function( e ) {
|
300 |
+
|
301 |
+
scheduleId = $( '[data-hmbkp-schedule-id]' ).attr( 'data-hmbkp-schedule-id' );
|
302 |
+
|
303 |
+
ajaxRequest = $.get(
|
304 |
+
ajaxurl,
|
305 |
+
{ 'action' : 'hmbkp_run_schedule', 'hmbkp_schedule_id' : scheduleId },
|
306 |
+
function( data ) {
|
307 |
+
|
308 |
+
if ( data.indexOf( 'hmbkp-schedule-actions' ) != -1 )
|
309 |
+
location.reload( true );
|
310 |
+
|
311 |
+
// The backup failed so just redirect back
|
312 |
+
else
|
313 |
+
location.replace( '//' + location.host + location.pathname + '?page=backupwordpress&action=hmbkp_cancel&reason=broken&hmbkp_schedule_id=' + scheduleId );
|
314 |
+
|
315 |
+
}
|
316 |
+
).error( function() {
|
317 |
+
location.replace( '//' + location.host + location.pathname + '?page=backupwordpress&action=hmbkp_cancel&reason=broken&hmbkp_schedule_id=' + scheduleId );
|
318 |
+
} );
|
319 |
+
|
320 |
+
$( this ).closest( '.hmbkp-schedule-sentence' ).addClass( 'hmbkp-running' );
|
321 |
|
322 |
+
hmbkpRedirectOnBackupComplete();
|
323 |
+
|
324 |
+
e.preventDefault();
|
325 |
+
|
326 |
+
} );
|
327 |
+
|
328 |
+
} );
|
329 |
|
330 |
+
function hmbkpRedirectOnBackupComplete( schedule_id ) {
|
331 |
|
332 |
+
jQuery.get(
|
333 |
+
ajaxurl,
|
334 |
+
{ 'action' : 'hmbkp_is_in_progress', 'hmbkp_schedule_id' : jQuery( '[data-hmbkp-schedule-id]' ).attr( 'data-hmbkp-schedule-id' ) },
|
335 |
function( data ) {
|
336 |
|
337 |
if ( data == 0 ) {
|
340 |
|
341 |
} else {
|
342 |
|
343 |
+
setTimeout( 'hmbkpRedirectOnBackupComplete();', 500 );
|
344 |
|
345 |
+
jQuery( '.hmbkp-schedule-actions' ).replaceWith( data );
|
346 |
|
347 |
}
|
348 |
}
|
assets/wpspin_light.gif
ADDED
Binary file
|
backupwordpress.mo
CHANGED
Binary file
|
backupwordpress.po
CHANGED
@@ -2,516 +2,563 @@ msgid ""
|
|
2 |
msgstr ""
|
3 |
"Project-Id-Version: BackUpWordPress\n"
|
4 |
"Report-Msgid-Bugs-To: \n"
|
5 |
-
"POT-Creation-Date: 2012-08-
|
6 |
-
"PO-Revision-Date: 2012-08-
|
7 |
-
"Last-Translator:
|
8 |
"Language-Team: Human Made Limited <support@humanmade.co.uk>\n"
|
9 |
-
"Language: \n"
|
10 |
"MIME-Version: 1.0\n"
|
11 |
"Content-Type: text/plain; charset=UTF-8\n"
|
12 |
"Content-Transfer-Encoding: 8bit\n"
|
13 |
-
"X-Poedit-KeywordsList: __;_e
|
14 |
"X-Poedit-Basepath: .\n"
|
15 |
-
"X-Poedit-Language: English\n"
|
16 |
-
"X-Poedit-Country: UNITED KINGDOM\n"
|
17 |
-
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
18 |
-
"X-Poedit-SourceCharset: utf-8\n"
|
19 |
"X-Poedit-SearchPath-0: .\n"
|
20 |
|
21 |
-
#:
|
22 |
-
|
23 |
-
msgid "Settings"
|
24 |
msgstr ""
|
25 |
|
26 |
-
#:
|
27 |
#, php-format
|
28 |
-
msgid "
|
29 |
msgstr ""
|
30 |
|
31 |
-
#: admin.
|
32 |
-
|
33 |
-
#: admin.menus.php:76
|
34 |
-
msgid "Constants"
|
35 |
msgstr ""
|
36 |
|
37 |
-
#:
|
38 |
-
msgid "
|
39 |
msgstr ""
|
40 |
|
41 |
-
#:
|
42 |
-
msgid "
|
|
|
|
|
|
|
|
|
43 |
msgstr ""
|
44 |
|
45 |
-
#:
|
46 |
-
msgid "
|
|
|
|
|
|
|
47 |
msgstr ""
|
48 |
|
49 |
-
#:
|
50 |
-
msgid "
|
|
|
|
|
|
|
51 |
msgstr ""
|
52 |
|
53 |
-
#:
|
54 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
55 |
msgstr ""
|
56 |
|
57 |
-
#: admin.
|
58 |
-
|
|
|
59 |
msgstr ""
|
60 |
|
61 |
-
#: admin.
|
62 |
-
|
|
|
|
|
|
|
|
|
63 |
msgstr ""
|
64 |
|
65 |
-
#: admin.
|
66 |
-
msgid "
|
67 |
msgstr ""
|
68 |
|
69 |
-
#: admin.
|
70 |
-
msgid "
|
71 |
msgstr ""
|
72 |
|
73 |
-
#: admin.
|
74 |
-
msgid "
|
75 |
msgstr ""
|
76 |
|
77 |
-
#: admin.
|
78 |
-
msgid "
|
79 |
msgstr ""
|
80 |
|
81 |
-
#: admin.
|
82 |
-
msgid "
|
83 |
msgstr ""
|
84 |
|
85 |
-
#: admin.
|
86 |
-
msgid "
|
87 |
msgstr ""
|
88 |
|
89 |
-
#: admin.
|
90 |
-
|
|
|
91 |
msgstr ""
|
92 |
|
93 |
-
#: admin.
|
94 |
-
msgid "
|
95 |
msgstr ""
|
96 |
|
97 |
-
#: admin.
|
98 |
-
msgid "
|
99 |
msgstr ""
|
100 |
|
101 |
-
#: admin.
|
102 |
-
|
103 |
-
msgid "The last %s backups will be stored on the server."
|
104 |
msgstr ""
|
105 |
|
106 |
-
#: admin.
|
107 |
-
msgid "
|
108 |
msgstr ""
|
109 |
|
110 |
-
#: admin.
|
111 |
-
msgid "
|
112 |
msgstr ""
|
113 |
|
114 |
-
#: admin.
|
115 |
-
|
|
|
|
|
|
|
116 |
msgstr ""
|
117 |
|
118 |
-
#: admin.
|
119 |
-
msgid "
|
120 |
msgstr ""
|
121 |
|
122 |
-
#: admin.
|
123 |
-
|
124 |
-
#: admin.constants.php:11
|
125 |
-
#: admin.constants.php:14
|
126 |
-
#: admin.constants.php:17
|
127 |
-
#: admin.constants.php:20
|
128 |
-
#: admin.constants.php:23
|
129 |
-
#: admin.constants.php:26
|
130 |
-
#: admin.constants.php:29
|
131 |
-
#: admin.constants.php:32
|
132 |
-
#: admin.constants.php:35
|
133 |
-
#: admin.constants.php:38
|
134 |
-
#: admin.constants.php:41
|
135 |
-
msgid "e.g."
|
136 |
msgstr ""
|
137 |
|
138 |
-
#: admin.
|
139 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
msgstr ""
|
141 |
|
142 |
-
#: admin.
|
143 |
#, php-format
|
144 |
-
msgid "
|
145 |
-
|
146 |
-
|
147 |
-
msgstr
|
148 |
|
149 |
-
#: admin.
|
150 |
-
|
|
|
151 |
msgstr ""
|
152 |
|
153 |
-
#: admin.
|
154 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
155 |
msgstr ""
|
156 |
|
157 |
-
#: admin.
|
158 |
#, php-format
|
159 |
-
msgid "
|
160 |
-
|
161 |
-
|
162 |
-
msgstr
|
163 |
|
164 |
-
#: admin.
|
165 |
#, php-format
|
166 |
-
msgid "
|
|
|
|
|
167 |
msgstr ""
|
168 |
|
169 |
-
#: admin.
|
170 |
-
|
171 |
-
msgid "
|
172 |
msgstr ""
|
173 |
|
174 |
-
#: admin.
|
175 |
-
|
|
|
176 |
msgstr ""
|
177 |
|
178 |
-
#: admin.
|
179 |
#, php-format
|
180 |
-
msgid "
|
|
|
|
|
181 |
msgstr ""
|
182 |
|
183 |
-
#: admin.
|
184 |
-
msgid "
|
|
|
|
|
185 |
msgstr ""
|
186 |
|
187 |
-
#: admin.
|
188 |
-
|
|
|
189 |
msgstr ""
|
190 |
|
191 |
-
#: admin
|
192 |
#, php-format
|
193 |
-
msgid "
|
194 |
msgstr ""
|
195 |
|
196 |
-
#: admin.
|
197 |
-
msgid "
|
198 |
msgstr ""
|
199 |
|
200 |
-
#: admin.
|
201 |
-
|
202 |
-
|
|
|
|
|
|
|
203 |
msgstr ""
|
204 |
|
205 |
-
#: admin.
|
206 |
#, php-format
|
207 |
-
msgid "
|
|
|
|
|
208 |
msgstr ""
|
209 |
|
210 |
-
#: admin.
|
211 |
-
|
212 |
-
#: admin.constants.php:23
|
213 |
-
#: admin.constants.php:26
|
214 |
-
#: admin.status.php:14
|
215 |
-
#: admin.status.php:18
|
216 |
-
msgid "database"
|
217 |
msgstr ""
|
218 |
|
219 |
-
#: admin.
|
220 |
-
|
221 |
-
msgid "The path to your %1$s executable. Will be used to zip up your %2$s and %3$s if available."
|
222 |
msgstr ""
|
223 |
|
224 |
-
#: admin.
|
225 |
-
|
226 |
-
#: admin.constants.php:26
|
227 |
-
#: admin.status.php:14
|
228 |
-
#: admin.status.php:22
|
229 |
-
msgid "files"
|
230 |
msgstr ""
|
231 |
|
232 |
-
#: admin.
|
233 |
-
|
234 |
-
msgid "Completely disables the automatic back up. You can still back up using the \"Back Up Now\" button. Defaults to %s."
|
235 |
msgstr ""
|
236 |
|
237 |
-
#: admin.
|
238 |
-
|
239 |
-
|
240 |
msgstr ""
|
241 |
|
242 |
-
#: admin.
|
243 |
-
#: admin.constants.php:26
|
244 |
#, php-format
|
245 |
-
msgid "
|
|
|
|
|
246 |
msgstr ""
|
247 |
|
248 |
-
#: admin.
|
249 |
-
|
250 |
-
msgid "The time that the daily back up should run. Defaults to %s."
|
251 |
msgstr ""
|
252 |
|
253 |
-
#: admin.
|
254 |
-
|
255 |
-
msgid "Attempt to email a copy of your backups. Value should be email address to send backups to. Defaults to %s."
|
256 |
msgstr ""
|
257 |
|
258 |
-
#: admin.
|
259 |
-
msgid "
|
260 |
msgstr ""
|
261 |
|
262 |
-
#: admin.
|
263 |
-
|
264 |
-
msgid "The capability to use when calling %1$s. Defaults to %2$s."
|
265 |
msgstr ""
|
266 |
|
267 |
-
#: admin.
|
268 |
-
|
269 |
-
msgid "The root directory that is backed up. Defaults to %s."
|
270 |
msgstr ""
|
271 |
|
272 |
-
#: admin.
|
273 |
-
msgid "
|
274 |
msgstr ""
|
275 |
|
276 |
-
#: admin.
|
277 |
-
|
278 |
-
msgid "%s is an invalid email address."
|
279 |
msgstr ""
|
280 |
|
281 |
-
#: admin.
|
282 |
-
|
283 |
-
#: functions/interface.functions.php:99
|
284 |
-
#: functions/interface.functions.php:110
|
285 |
-
#: functions/interface.functions.php:120
|
286 |
-
#: functions/interface.functions.php:130
|
287 |
-
#: functions/interface.functions.php:140
|
288 |
-
#: functions/interface.functions.php:150
|
289 |
-
msgid "BackUpWordPress has detected a problem."
|
290 |
msgstr ""
|
291 |
|
292 |
-
#: admin.
|
|
|
|
|
|
|
|
|
293 |
#, php-format
|
294 |
-
msgid "
|
295 |
msgstr ""
|
296 |
|
297 |
-
#: admin.
|
298 |
-
|
299 |
-
msgid "Backups"
|
300 |
msgstr ""
|
301 |
|
302 |
-
#: admin.
|
303 |
-
msgid "
|
304 |
msgstr ""
|
305 |
|
306 |
-
#: admin.
|
307 |
-
|
308 |
-
msgid "The information below is for version %1$s. View the <code>readme.txt</code> file for help specific to version %2$s."
|
309 |
msgstr ""
|
310 |
|
311 |
-
#: admin.
|
312 |
-
msgid "
|
313 |
msgstr ""
|
314 |
|
315 |
-
#: admin.
|
316 |
-
msgid "
|
317 |
msgstr ""
|
318 |
|
319 |
-
#: admin.
|
320 |
-
msgid "
|
321 |
msgstr ""
|
322 |
|
323 |
-
#: admin.
|
324 |
-
msgid "
|
325 |
msgstr ""
|
326 |
|
327 |
-
#:
|
328 |
-
msgid "
|
329 |
msgstr ""
|
330 |
|
331 |
-
#:
|
332 |
-
|
333 |
-
|
|
|
|
|
|
|
|
|
|
|
334 |
msgstr ""
|
335 |
|
336 |
-
#: admin.
|
337 |
#, php-format
|
338 |
-
msgid "
|
339 |
msgstr ""
|
340 |
|
341 |
-
#: admin.
|
342 |
-
|
|
|
343 |
msgstr ""
|
344 |
|
345 |
-
#: admin.
|
346 |
-
|
|
|
347 |
msgstr ""
|
348 |
|
349 |
-
#: admin.
|
350 |
#, php-format
|
351 |
-
msgid "
|
352 |
-
|
353 |
-
msgstr[0] ""
|
354 |
-
msgstr[1] ""
|
355 |
|
356 |
-
#: admin.
|
357 |
#, php-format
|
358 |
-
msgid "
|
359 |
msgstr ""
|
360 |
|
361 |
-
#: admin.
|
362 |
#, php-format
|
363 |
-
msgid "
|
364 |
msgstr ""
|
365 |
|
366 |
-
#: admin.
|
367 |
-
msgid "
|
368 |
msgstr ""
|
369 |
|
370 |
-
#: admin.
|
371 |
#, php-format
|
372 |
-
msgid "
|
373 |
msgstr ""
|
374 |
|
375 |
-
#: admin.
|
376 |
#, php-format
|
377 |
-
msgid "
|
378 |
msgstr ""
|
379 |
|
380 |
-
#:
|
381 |
-
|
|
|
382 |
msgstr ""
|
383 |
|
384 |
-
#:
|
385 |
-
|
|
|
386 |
msgstr ""
|
387 |
|
388 |
-
#:
|
389 |
-
msgid "
|
390 |
msgstr ""
|
391 |
|
392 |
-
#:
|
393 |
-
msgid "
|
394 |
msgstr ""
|
395 |
|
396 |
-
#:
|
397 |
-
|
|
|
398 |
msgstr ""
|
399 |
|
400 |
-
#:
|
401 |
-
|
402 |
-
msgid "
|
403 |
msgstr ""
|
404 |
|
405 |
-
#:
|
406 |
#, php-format
|
407 |
-
msgid "
|
408 |
msgstr ""
|
409 |
|
410 |
-
#:
|
411 |
#, php-format
|
412 |
-
msgid "
|
413 |
msgstr ""
|
414 |
|
415 |
-
#:
|
416 |
-
|
417 |
-
msgid " %1$s is running in %2$s. Please contact your host and ask them to disable %3$s."
|
418 |
msgstr ""
|
419 |
|
420 |
-
#:
|
421 |
-
msgid "
|
422 |
msgstr ""
|
423 |
|
424 |
-
#:
|
425 |
-
msgid "
|
|
|
|
|
|
|
|
|
426 |
msgstr ""
|
427 |
|
428 |
-
#: functions/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
429 |
#, php-format
|
430 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
431 |
msgstr ""
|
432 |
|
433 |
-
#: functions/interface.
|
434 |
#, php-format
|
435 |
-
msgid "
|
436 |
-
|
437 |
-
|
438 |
-
msgstr
|
439 |
|
440 |
-
#: functions/interface.
|
441 |
-
|
|
|
|
|
|
|
442 |
msgstr ""
|
443 |
|
444 |
-
#: functions/interface.
|
445 |
#, php-format
|
446 |
-
msgid "
|
|
|
|
|
|
|
|
|
|
|
|
|
447 |
msgstr ""
|
448 |
|
449 |
-
#: functions/interface.
|
|
|
|
|
|
|
|
|
450 |
#, php-format
|
451 |
-
msgid "
|
|
|
|
|
452 |
msgstr ""
|
453 |
|
454 |
-
#: functions/interface.
|
455 |
#, php-format
|
456 |
-
msgid "
|
|
|
|
|
457 |
msgstr ""
|
458 |
|
459 |
-
#: functions/interface.
|
460 |
msgid "BackUpWordPress detected issues with your last backup."
|
461 |
msgstr ""
|
462 |
|
463 |
-
#: functions/
|
464 |
-
msgid "
|
465 |
msgstr ""
|
466 |
|
467 |
-
#: functions/
|
468 |
-
msgid "
|
469 |
msgstr ""
|
470 |
|
471 |
-
#: functions/
|
472 |
-
msgid "
|
473 |
msgstr ""
|
474 |
|
475 |
-
#: functions/
|
476 |
-
|
477 |
-
#, php-format
|
478 |
-
msgid "Backup of %s"
|
479 |
msgstr ""
|
480 |
|
481 |
-
#: functions/
|
482 |
-
|
483 |
-
msgid ""
|
484 |
-
"BackUpWordPress has completed a backup of your site %1$s.\\n"
|
485 |
-
"\\n"
|
486 |
-
"The backup file should be attached to this email.\\n"
|
487 |
-
"\\n"
|
488 |
-
"You can also download the backup file by clicking the link below:\\n"
|
489 |
-
"\\n"
|
490 |
-
"%2$s\\n"
|
491 |
-
"\\n"
|
492 |
-
"Kind Regards\\n"
|
493 |
-
"\\n"
|
494 |
-
" The Happy BackUpWordPress Backup Emailing Robot"
|
495 |
msgstr ""
|
496 |
|
497 |
-
#: functions/
|
498 |
-
|
499 |
-
msgid ""
|
500 |
-
"BackUpWordPress has completed a backup of your site %1$s.\\n"
|
501 |
-
"\\n"
|
502 |
-
"Unfortunately the backup file was too large to attach to this email.\\n"
|
503 |
-
"\\n"
|
504 |
-
"You can download the backup file by clicking the link below:\\n"
|
505 |
-
"\\n"
|
506 |
-
"%2$s\\n"
|
507 |
-
"\\n"
|
508 |
-
"Kind Regards\\n"
|
509 |
-
"\\n"
|
510 |
-
" The Happy BackUpWordPress Backup Emailing Robot"
|
511 |
msgstr ""
|
512 |
|
513 |
-
#: functions/
|
514 |
-
|
515 |
-
msgid "This %s file ensures that other people cannot download your backup files."
|
516 |
msgstr ""
|
517 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
msgstr ""
|
3 |
"Project-Id-Version: BackUpWordPress\n"
|
4 |
"Report-Msgid-Bugs-To: \n"
|
5 |
+
"POT-Creation-Date: 2012-08-22 15:46-0000\n"
|
6 |
+
"PO-Revision-Date: 2012-08-22 15:47-0000\n"
|
7 |
+
"Last-Translator: Tom Willmot <tom@humanmade.co.uk>\n"
|
8 |
"Language-Team: Human Made Limited <support@humanmade.co.uk>\n"
|
9 |
+
"Language: en_GB\n"
|
10 |
"MIME-Version: 1.0\n"
|
11 |
"Content-Type: text/plain; charset=UTF-8\n"
|
12 |
"Content-Transfer-Encoding: 8bit\n"
|
13 |
+
"X-Poedit-KeywordsList: __;_e\n"
|
14 |
"X-Poedit-Basepath: .\n"
|
|
|
|
|
|
|
|
|
15 |
"X-Poedit-SearchPath-0: .\n"
|
16 |
|
17 |
+
#: plugin.php:52
|
18 |
+
msgid "BackUpWordPress requires PHP version 5.2.4 or greater."
|
|
|
19 |
msgstr ""
|
20 |
|
21 |
+
#: plugin.php:63
|
22 |
#, php-format
|
23 |
+
msgid "BackUpWordPress requires WordPress version %s or greater."
|
24 |
msgstr ""
|
25 |
|
26 |
+
#: plugin.php:95 admin/schedule-form.php:52
|
27 |
+
msgid "Update"
|
|
|
|
|
28 |
msgstr ""
|
29 |
|
30 |
+
#: plugin.php:96
|
31 |
+
msgid "Cancel"
|
32 |
msgstr ""
|
33 |
|
34 |
+
#: plugin.php:97
|
35 |
+
msgid ""
|
36 |
+
"Are you sure you want to delete this schedule? All of it's backups will also "
|
37 |
+
"be deleted.\n"
|
38 |
+
"\n"
|
39 |
+
"'Cancel' to go back, 'OK' to delete.\n"
|
40 |
msgstr ""
|
41 |
|
42 |
+
#: plugin.php:98
|
43 |
+
msgid ""
|
44 |
+
"Are you sure you want to delete this backup?\n"
|
45 |
+
"\n"
|
46 |
+
"'Cancel' to go back, 'OK' to delete.\n"
|
47 |
msgstr ""
|
48 |
|
49 |
+
#: plugin.php:99
|
50 |
+
msgid ""
|
51 |
+
"Are you sure you want to remove this exclude rule?\n"
|
52 |
+
"\n"
|
53 |
+
"'Cancel' to go back, 'OK' to delete.\n"
|
54 |
msgstr ""
|
55 |
|
56 |
+
#: plugin.php:100
|
57 |
+
msgid ""
|
58 |
+
"Reducing the number of backups that are stored on this server will cause "
|
59 |
+
"some of your existing backups to be deleted, are you sure that's what you "
|
60 |
+
"want?\n"
|
61 |
+
"\n"
|
62 |
+
"'Cancel' to go back, 'OK' to delete.\n"
|
63 |
msgstr ""
|
64 |
|
65 |
+
#: admin/actions.php:163 functions/interface.php:72 functions/interface.php:82
|
66 |
+
#: functions/interface.php:92
|
67 |
+
msgid "BackUpWordPress has detected a problem."
|
68 |
msgstr ""
|
69 |
|
70 |
+
#: admin/actions.php:163
|
71 |
+
#, php-format
|
72 |
+
msgid ""
|
73 |
+
"%1$s is returning a %2$s response which could mean cron jobs aren't getting "
|
74 |
+
"fired properly. BackUpWordPress relies on wp-cron to run scheduled back ups. "
|
75 |
+
"See the %3$s for more details."
|
76 |
msgstr ""
|
77 |
|
78 |
+
#: admin/actions.php:232
|
79 |
+
msgid "Backup type cannot be empty"
|
80 |
msgstr ""
|
81 |
|
82 |
+
#: admin/actions.php:235
|
83 |
+
msgid "Invalid backup type"
|
84 |
msgstr ""
|
85 |
|
86 |
+
#: admin/actions.php:245
|
87 |
+
msgid "Schedule cannot be empty"
|
88 |
msgstr ""
|
89 |
|
90 |
+
#: admin/actions.php:248
|
91 |
+
msgid "Invalid schedule"
|
92 |
msgstr ""
|
93 |
|
94 |
+
#: admin/actions.php:258
|
95 |
+
msgid "Max backups must be more than 1"
|
96 |
msgstr ""
|
97 |
|
98 |
+
#: admin/actions.php:261
|
99 |
+
msgid "Max backups must be a number"
|
100 |
msgstr ""
|
101 |
|
102 |
+
#: admin/actions.php:338
|
103 |
+
#, php-format
|
104 |
+
msgid "%s didn't match any files."
|
105 |
msgstr ""
|
106 |
|
107 |
+
#: admin/backups.php:13
|
108 |
+
msgid "add schedule"
|
109 |
msgstr ""
|
110 |
|
111 |
+
#: admin/backups.php:37
|
112 |
+
msgid "Size"
|
113 |
msgstr ""
|
114 |
|
115 |
+
#: admin/backups.php:38
|
116 |
+
msgid "Type"
|
|
|
117 |
msgstr ""
|
118 |
|
119 |
+
#: admin/backups.php:39
|
120 |
+
msgid "Actions"
|
121 |
msgstr ""
|
122 |
|
123 |
+
#: admin/backups.php:62
|
124 |
+
msgid "This is where your backups will appear once you have one."
|
125 |
msgstr ""
|
126 |
|
127 |
+
#: admin/constants.php:3
|
128 |
+
#, php-format
|
129 |
+
msgid ""
|
130 |
+
"You can %1$s any of the following %2$s in your %3$s to control advanced "
|
131 |
+
"settings. %4$s. Defined %5$s will be highlighted."
|
132 |
msgstr ""
|
133 |
|
134 |
+
#: admin/constants.php:3 admin/menu.php:76
|
135 |
+
msgid "Constants"
|
136 |
msgstr ""
|
137 |
|
138 |
+
#: admin/constants.php:3
|
139 |
+
msgid "The Codex can help"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
140 |
msgstr ""
|
141 |
|
142 |
+
#: admin/constants.php:8
|
143 |
+
#, php-format
|
144 |
+
msgid ""
|
145 |
+
"The path to folder you would like to store your backup files in, defaults to "
|
146 |
+
"%s."
|
147 |
+
msgstr ""
|
148 |
+
|
149 |
+
#: admin/constants.php:8 admin/constants.php:11 admin/constants.php:14
|
150 |
+
#: admin/constants.php:17 admin/constants.php:20 admin/constants.php:23
|
151 |
+
#: admin/constants.php:26 admin/constants.php:29 admin/constants.php:32
|
152 |
+
#: admin/constants.php:35 admin/constants.php:38 admin/constants.php:41
|
153 |
+
msgid "e.g."
|
154 |
msgstr ""
|
155 |
|
156 |
+
#: admin/constants.php:11
|
157 |
#, php-format
|
158 |
+
msgid ""
|
159 |
+
"The path to your %1$s executable. Will be used for the %2$s part of the back "
|
160 |
+
"up if available."
|
161 |
+
msgstr ""
|
162 |
|
163 |
+
#: admin/constants.php:11 admin/constants.php:14 admin/constants.php:23
|
164 |
+
#: admin/constants.php:26
|
165 |
+
msgid "database"
|
166 |
msgstr ""
|
167 |
|
168 |
+
#: admin/constants.php:14
|
169 |
+
#, php-format
|
170 |
+
msgid ""
|
171 |
+
"The path to your %1$s executable. Will be used to zip up your %2$s and %3$s "
|
172 |
+
"if available."
|
173 |
+
msgstr ""
|
174 |
+
|
175 |
+
#: admin/constants.php:14 admin/constants.php:23 admin/constants.php:26
|
176 |
+
msgid "files"
|
177 |
msgstr ""
|
178 |
|
179 |
+
#: admin/constants.php:17
|
180 |
#, php-format
|
181 |
+
msgid ""
|
182 |
+
"Completely disables the automatic back up. You can still back up using the "
|
183 |
+
"\"Back Up Now\" button. Defaults to %s."
|
184 |
+
msgstr ""
|
185 |
|
186 |
+
#: admin/constants.php:20
|
187 |
#, php-format
|
188 |
+
msgid ""
|
189 |
+
"Number of backups to keep, older backups will be deleted automatically when "
|
190 |
+
"a new backup is completed. Defaults to %s."
|
191 |
msgstr ""
|
192 |
|
193 |
+
#: admin/constants.php:23 admin/constants.php:26
|
194 |
+
#, php-format
|
195 |
+
msgid "Backup %1$s only, your %2$s won't be backed up. Defaults to %3$s."
|
196 |
msgstr ""
|
197 |
|
198 |
+
#: admin/constants.php:29
|
199 |
+
#, php-format
|
200 |
+
msgid "The time that the daily back up should run. Defaults to %s."
|
201 |
msgstr ""
|
202 |
|
203 |
+
#: admin/constants.php:32
|
204 |
#, php-format
|
205 |
+
msgid ""
|
206 |
+
"Attempt to email a copy of your backups. Value should be email address to "
|
207 |
+
"send backups to. Defaults to %s."
|
208 |
msgstr ""
|
209 |
|
210 |
+
#: admin/constants.php:35
|
211 |
+
msgid ""
|
212 |
+
"Comma separated list of files or directories to exclude, the backups "
|
213 |
+
"directory is automatically excluded."
|
214 |
msgstr ""
|
215 |
|
216 |
+
#: admin/constants.php:38
|
217 |
+
#, php-format
|
218 |
+
msgid "The capability to use when calling %1$s. Defaults to %2$s."
|
219 |
msgstr ""
|
220 |
|
221 |
+
#: admin/constants.php:41
|
222 |
#, php-format
|
223 |
+
msgid "The root directory that is backed up. Defaults to %s."
|
224 |
msgstr ""
|
225 |
|
226 |
+
#: admin/menu.php:10 admin/page.php:5
|
227 |
+
msgid "Manage Backups"
|
228 |
msgstr ""
|
229 |
|
230 |
+
#: admin/menu.php:10 admin/menu.php:34
|
231 |
+
msgid "Backups"
|
232 |
+
msgstr ""
|
233 |
+
|
234 |
+
#: admin/menu.php:69
|
235 |
+
msgid "You are not using the latest stable version of BackUpWordPress"
|
236 |
msgstr ""
|
237 |
|
238 |
+
#: admin/menu.php:69
|
239 |
#, php-format
|
240 |
+
msgid ""
|
241 |
+
"The information below is for version %1$s. View the %2$s file for help "
|
242 |
+
"specific to version %3$s."
|
243 |
msgstr ""
|
244 |
|
245 |
+
#: admin/menu.php:75
|
246 |
+
msgid "FAQ"
|
|
|
|
|
|
|
|
|
|
|
247 |
msgstr ""
|
248 |
|
249 |
+
#: admin/menu.php:79
|
250 |
+
msgid "For more information:"
|
|
|
251 |
msgstr ""
|
252 |
|
253 |
+
#: admin/menu.php:81
|
254 |
+
msgid "Support Forums"
|
|
|
|
|
|
|
|
|
255 |
msgstr ""
|
256 |
|
257 |
+
#: admin/menu.php:82
|
258 |
+
msgid "Help with translation"
|
|
|
259 |
msgstr ""
|
260 |
|
261 |
+
#: admin/page.php:13
|
262 |
+
msgid ""
|
263 |
+
"You need to fix the issues detailed above before BackUpWordPress can start."
|
264 |
msgstr ""
|
265 |
|
266 |
+
#: admin/page.php:17
|
|
|
267 |
#, php-format
|
268 |
+
msgid ""
|
269 |
+
"If you need help getting things working you are more than welcome to email "
|
270 |
+
"us at %s and we'll do what we can."
|
271 |
msgstr ""
|
272 |
|
273 |
+
#: admin/schedule-form-excludes.php:7
|
274 |
+
msgid "Manage Exclude"
|
|
|
275 |
msgstr ""
|
276 |
|
277 |
+
#: admin/schedule-form-excludes.php:13
|
278 |
+
msgid "New Exclude Rule"
|
|
|
279 |
msgstr ""
|
280 |
|
281 |
+
#: admin/schedule-form-excludes.php:17
|
282 |
+
msgid "Preview"
|
283 |
msgstr ""
|
284 |
|
285 |
+
#: admin/schedule-form-excludes.php:27
|
286 |
+
msgid "Exclude Rules"
|
|
|
287 |
msgstr ""
|
288 |
|
289 |
+
#: admin/schedule-form-excludes.php:42
|
290 |
+
msgid "Remove"
|
|
|
291 |
msgstr ""
|
292 |
|
293 |
+
#: admin/schedule-form-excludes.php:59
|
294 |
+
msgid "Excluded"
|
295 |
msgstr ""
|
296 |
|
297 |
+
#: admin/schedule-form-excludes.php:60
|
298 |
+
msgid "Included"
|
|
|
299 |
msgstr ""
|
300 |
|
301 |
+
#: admin/schedule-form-excludes.php:63
|
302 |
+
msgid "Unreadable"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
303 |
msgstr ""
|
304 |
|
305 |
+
#: admin/schedule-form-excludes.php:86
|
306 |
+
msgid "Unreadable files can't be backed up"
|
307 |
+
msgstr ""
|
308 |
+
|
309 |
+
#: admin/schedule-form-excludes.php:92
|
310 |
#, php-format
|
311 |
+
msgid "Your site is %s. Backups will be compressed and so will be smaller."
|
312 |
msgstr ""
|
313 |
|
314 |
+
#: admin/schedule-form-excludes.php:98
|
315 |
+
msgid "Close"
|
|
|
316 |
msgstr ""
|
317 |
|
318 |
+
#: admin/schedule-form.php:7
|
319 |
+
msgid "Schedule Settings"
|
320 |
msgstr ""
|
321 |
|
322 |
+
#: admin/schedule-form.php:11
|
323 |
+
msgid "Backup"
|
|
|
324 |
msgstr ""
|
325 |
|
326 |
+
#: admin/schedule-form.php:14
|
327 |
+
msgid "Both Database & files"
|
328 |
msgstr ""
|
329 |
|
330 |
+
#: admin/schedule-form.php:15
|
331 |
+
msgid "Files only"
|
332 |
msgstr ""
|
333 |
|
334 |
+
#: admin/schedule-form.php:16
|
335 |
+
msgid "Database only"
|
336 |
msgstr ""
|
337 |
|
338 |
+
#: admin/schedule-form.php:23
|
339 |
+
msgid "Schedule"
|
340 |
msgstr ""
|
341 |
|
342 |
+
#: admin/schedule-form.php:39
|
343 |
+
msgid "Number of backups to store on this server"
|
344 |
msgstr ""
|
345 |
|
346 |
+
#: admin/schedule-form.php:43
|
347 |
+
msgid ""
|
348 |
+
"The number of previous backups to store on the server. past this limit the "
|
349 |
+
"oldest backups will be deleted automatically."
|
350 |
+
msgstr ""
|
351 |
+
|
352 |
+
#: admin/schedule.php:16
|
353 |
+
msgid "hourly on the hour"
|
354 |
msgstr ""
|
355 |
|
356 |
+
#: admin/schedule.php:16
|
357 |
#, php-format
|
358 |
+
msgid "hourly at %s minutes past the hour"
|
359 |
msgstr ""
|
360 |
|
361 |
+
#: admin/schedule.php:22
|
362 |
+
#, php-format
|
363 |
+
msgid "daily at %s"
|
364 |
msgstr ""
|
365 |
|
366 |
+
#: admin/schedule.php:34
|
367 |
+
#, php-format
|
368 |
+
msgid "every 12 hours at %s & %s"
|
369 |
msgstr ""
|
370 |
|
371 |
+
#: admin/schedule.php:40
|
372 |
#, php-format
|
373 |
+
msgid "weekly on %s at %s"
|
374 |
+
msgstr ""
|
|
|
|
|
375 |
|
376 |
+
#: admin/schedule.php:46
|
377 |
#, php-format
|
378 |
+
msgid "fortnightly on %s at %s"
|
379 |
msgstr ""
|
380 |
|
381 |
+
#: admin/schedule.php:53
|
382 |
#, php-format
|
383 |
+
msgid "on the %s of each month at %s"
|
384 |
msgstr ""
|
385 |
|
386 |
+
#: admin/schedule.php:59
|
387 |
+
msgid "server"
|
388 |
msgstr ""
|
389 |
|
390 |
+
#: admin/schedule.php:66
|
391 |
#, php-format
|
392 |
+
msgid "store the only the last backup %s"
|
393 |
msgstr ""
|
394 |
|
395 |
+
#: admin/schedule.php:72
|
396 |
#, php-format
|
397 |
+
msgid "don't store any backups %s"
|
398 |
msgstr ""
|
399 |
|
400 |
+
#: admin/schedule.php:78
|
401 |
+
#, php-format
|
402 |
+
msgid "store only the last %s backups %s"
|
403 |
msgstr ""
|
404 |
|
405 |
+
#: admin/schedule.php:87
|
406 |
+
#, php-format
|
407 |
+
msgid "Backup my %s %s %s, %s. %s"
|
408 |
msgstr ""
|
409 |
|
410 |
+
#: admin/schedule.php:87
|
411 |
+
msgid "Backups will be compressed and should be smaller than this."
|
412 |
msgstr ""
|
413 |
|
414 |
+
#: classes/email.php:19
|
415 |
+
msgid "Email notification"
|
416 |
msgstr ""
|
417 |
|
418 |
+
#: classes/email.php:50
|
419 |
+
#, php-format
|
420 |
+
msgid "Send an email notification to %s"
|
421 |
msgstr ""
|
422 |
|
423 |
+
#: classes/email.php:72
|
424 |
+
#, php-format
|
425 |
+
msgid "%s isn't a valid email"
|
426 |
msgstr ""
|
427 |
|
428 |
+
#: classes/email.php:127
|
429 |
#, php-format
|
430 |
+
msgid "Backup of %s Failed"
|
431 |
msgstr ""
|
432 |
|
433 |
+
#: classes/email.php:137
|
434 |
#, php-format
|
435 |
+
msgid "Backup of %s"
|
436 |
msgstr ""
|
437 |
|
438 |
+
#: classes/schedule.php:460
|
439 |
+
msgid "Backup started"
|
|
|
440 |
msgstr ""
|
441 |
|
442 |
+
#: classes/schedule.php:511
|
443 |
+
msgid "Creating zip archive"
|
444 |
msgstr ""
|
445 |
|
446 |
+
#: classes/schedule.php:517
|
447 |
+
msgid "Dumping database"
|
448 |
+
msgstr ""
|
449 |
+
|
450 |
+
#: functions/core.php:192
|
451 |
+
msgid "BackUpWordPress has setup your default schedules."
|
452 |
msgstr ""
|
453 |
|
454 |
+
#: functions/core.php:192
|
455 |
+
msgid ""
|
456 |
+
"By default BackUpWordPress performs a daily backup of your database and a "
|
457 |
+
"weekly backup of your database & files. You can modify these schedules "
|
458 |
+
"below."
|
459 |
+
msgstr ""
|
460 |
+
|
461 |
+
#: functions/core.php:273
|
462 |
#, php-format
|
463 |
+
msgid ""
|
464 |
+
"This %s file ensures that other people cannot download your backup files."
|
465 |
+
msgstr ""
|
466 |
+
|
467 |
+
#: functions/interface.php:27
|
468 |
+
msgid "Download"
|
469 |
+
msgstr ""
|
470 |
+
|
471 |
+
#: functions/interface.php:28 functions/interface.php:215
|
472 |
+
msgid "Delete"
|
473 |
+
msgstr ""
|
474 |
+
|
475 |
+
#: functions/interface.php:50 functions/interface.php:62
|
476 |
+
msgid "BackUpWordPress is almost ready."
|
477 |
msgstr ""
|
478 |
|
479 |
+
#: functions/interface.php:50
|
480 |
#, php-format
|
481 |
+
msgid ""
|
482 |
+
"The backups directory can't be created because your %1$s directory isn't "
|
483 |
+
"writable, run %2$s or %3$s or create the folder yourself."
|
484 |
+
msgstr ""
|
485 |
|
486 |
+
#: functions/interface.php:62
|
487 |
+
#, php-format
|
488 |
+
msgid ""
|
489 |
+
"Your backups directory isn't writable, run %1$s or %2$s or set the "
|
490 |
+
"permissions yourself."
|
491 |
msgstr ""
|
492 |
|
493 |
+
#: functions/interface.php:72
|
494 |
#, php-format
|
495 |
+
msgid ""
|
496 |
+
"%1$s is running in %2$s. Please contact your host and ask them to disable "
|
497 |
+
"%3$s."
|
498 |
+
msgstr ""
|
499 |
+
|
500 |
+
#: functions/interface.php:72
|
501 |
+
msgid "http://php.net/manual/en/features.safe-mode.php"
|
502 |
msgstr ""
|
503 |
|
504 |
+
#: functions/interface.php:72
|
505 |
+
msgid "Safe Mode"
|
506 |
+
msgstr ""
|
507 |
+
|
508 |
+
#: functions/interface.php:82
|
509 |
#, php-format
|
510 |
+
msgid ""
|
511 |
+
"Your custom backups directory %1$s doesn't exist and can't be created, your "
|
512 |
+
"backups will be saved to %2$s instead."
|
513 |
msgstr ""
|
514 |
|
515 |
+
#: functions/interface.php:92
|
516 |
#, php-format
|
517 |
+
msgid ""
|
518 |
+
"Your custom backups directory %1$s isn't writable, new backups will be saved "
|
519 |
+
"to %2$s instead."
|
520 |
msgstr ""
|
521 |
|
522 |
+
#: functions/interface.php:102
|
523 |
msgid "BackUpWordPress detected issues with your last backup."
|
524 |
msgstr ""
|
525 |
|
526 |
+
#: functions/interface.php:182
|
527 |
+
msgid "Database and Files"
|
528 |
msgstr ""
|
529 |
|
530 |
+
#: functions/interface.php:185
|
531 |
+
msgid "Files"
|
532 |
msgstr ""
|
533 |
|
534 |
+
#: functions/interface.php:188
|
535 |
+
msgid "Database"
|
536 |
msgstr ""
|
537 |
|
538 |
+
#: functions/interface.php:193
|
539 |
+
msgid "Unknown"
|
|
|
|
|
540 |
msgstr ""
|
541 |
|
542 |
+
#: functions/interface.php:201
|
543 |
+
msgid "cancel"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
544 |
msgstr ""
|
545 |
|
546 |
+
#: functions/interface.php:207
|
547 |
+
msgid "Settings"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
548 |
msgstr ""
|
549 |
|
550 |
+
#: functions/interface.php:210
|
551 |
+
msgid "Excludes"
|
|
|
552 |
msgstr ""
|
553 |
|
554 |
+
#: functions/interface.php:213
|
555 |
+
msgid "Run now"
|
556 |
+
msgstr ""
|
557 |
+
|
558 |
+
#: hm-backup/hm-backup.php:892
|
559 |
+
msgid "The backup file was not created"
|
560 |
+
msgstr ""
|
561 |
+
|
562 |
+
#: hm-backup/hm-backup.php:963
|
563 |
+
msgid "The following files are unreadable and couldn't be backed up: "
|
564 |
+
msgstr ""
|
classes/email.php
ADDED
@@ -0,0 +1,164 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Email notifications for backups
|
5 |
+
*
|
6 |
+
* @extends HMBKP_Service
|
7 |
+
*/
|
8 |
+
class HMBKP_Email_Service extends HMBKP_Service {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* Output the email form field
|
12 |
+
*
|
13 |
+
* @access public
|
14 |
+
*/
|
15 |
+
public function field() { ?>
|
16 |
+
|
17 |
+
<label>
|
18 |
+
|
19 |
+
<?php _e( 'Email notification', 'hmbkp' ); ?>
|
20 |
+
|
21 |
+
<input type="email" name="<?php echo $this->get_field_name( 'email' ); ?>" value="<?php echo $this->get_field_value( 'email' ); ?>" />
|
22 |
+
|
23 |
+
<p class="description"><?php _e( 'Receive a notification email when a backup completes, if the backup is small enough (< 10mb) then it will be attached to the email. Separate multiple email address\'s with a comma.', 'hmbkp' ); ?></p>
|
24 |
+
|
25 |
+
</label>
|
26 |
+
|
27 |
+
<?php }
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Not used as we only need a field
|
31 |
+
*
|
32 |
+
* @see field
|
33 |
+
* @return string Empty string
|
34 |
+
*/
|
35 |
+
public function form() {
|
36 |
+
return '';
|
37 |
+
}
|
38 |
+
|
39 |
+
/**
|
40 |
+
* The sentence fragment that is output as part of the schedule sentence
|
41 |
+
*
|
42 |
+
* @return string The sentence fragment
|
43 |
+
*/
|
44 |
+
public function display() {
|
45 |
+
|
46 |
+
if ( $emails = $this->get_email_address_array() ) {
|
47 |
+
|
48 |
+
$email = '<code>' . implode( '</code>, <code>', $emails ) . '</code>';
|
49 |
+
|
50 |
+
return sprintf( __( 'Send an email notification to %s', 'hmbkp' ), $email );
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
+
}
|
55 |
+
|
56 |
+
/**
|
57 |
+
* Validate the email and return an error if validation fails
|
58 |
+
*
|
59 |
+
* @param array &$new_data Array of new data, passed by reference
|
60 |
+
* @param array $old_data The data we are replacing
|
61 |
+
* @return null|array Null on success, array of errors if validation failed
|
62 |
+
*/
|
63 |
+
public function update( &$new_data, $old_data ) {
|
64 |
+
|
65 |
+
$errors = array();
|
66 |
+
|
67 |
+
if ( isset( $new_data['email'] ) ) {
|
68 |
+
|
69 |
+
if ( ! empty( $new_data['email'] ) )
|
70 |
+
foreach( explode( ',', $new_data['email'] ) as $email )
|
71 |
+
if ( ! is_email( trim( $email ) ) )
|
72 |
+
$errors['email'] = sprintf( __( '%s isn\'t a valid email', 'hmbkp' ), esc_attr( $email ) );
|
73 |
+
|
74 |
+
|
75 |
+
if ( ! empty( $errors['email'] ) )
|
76 |
+
$new_data['email'] = '';
|
77 |
+
|
78 |
+
}
|
79 |
+
|
80 |
+
return $errors;
|
81 |
+
|
82 |
+
}
|
83 |
+
|
84 |
+
/**
|
85 |
+
* Get an array or validated email address's
|
86 |
+
* @return array An array of validated email address's
|
87 |
+
*/
|
88 |
+
private function get_email_address_array() {
|
89 |
+
|
90 |
+
$emails = array_map( 'trim', explode( ',', $this->get_field_value( 'email' ) ) );
|
91 |
+
|
92 |
+
return array_filter( array_unique( $emails ), 'is_email' );
|
93 |
+
|
94 |
+
}
|
95 |
+
|
96 |
+
/**
|
97 |
+
* Fire the email notification on the hmbkp_backup_complete
|
98 |
+
*
|
99 |
+
* @see HM_Backup::do_action
|
100 |
+
* @param string $action The action received from the backup
|
101 |
+
* @return void
|
102 |
+
*/
|
103 |
+
public function action( $action ) {
|
104 |
+
|
105 |
+
if ( $action == 'hmbkp_backup_complete' && $this->get_email_address_array() ) {
|
106 |
+
|
107 |
+
$file = $this->schedule->get_archive_filepath();
|
108 |
+
|
109 |
+
$sent = false;
|
110 |
+
|
111 |
+
$download = add_query_arg( 'hmbkp_download', base64_encode( $file ), HMBKP_ADMIN_URL );
|
112 |
+
$domain = parse_url( home_url(), PHP_URL_HOST ) . parse_url( home_url(), PHP_URL_PATH );
|
113 |
+
|
114 |
+
$headers = 'From: BackUpWordPress <' . get_bloginfo( 'admin_email' ) . '>' . "\r\n";
|
115 |
+
|
116 |
+
// The backup failed, send a message saying as much
|
117 |
+
if ( file_exists( $file ) && ( $errors = array_merge( $this->schedule->get_errors(), $this->schedule->get_warnings() ) ) ) {
|
118 |
+
|
119 |
+
$error_message = '';
|
120 |
+
|
121 |
+
foreach ( $errors as $error_set )
|
122 |
+
$error_message .= implode( "\n - ", $error_set );
|
123 |
+
|
124 |
+
if ( $error_message )
|
125 |
+
$error_message = ' - ' . $error_message;
|
126 |
+
|
127 |
+
$subject = sprintf( __( 'Backup of %s Failed', 'hmbkp' ), $domain );
|
128 |
+
|
129 |
+
$message = sprintf( __( 'BackUpWordPress was unable to backup your site %1$s.', 'hmbkp' ) . "\n\n" . __( 'Here are the errors that we\'re encountered:', 'hmbkp' ) . "\n\n" . '%2$s' . "\n\n" . __( 'If the errors above look like Martian, forward this email to %3$s and we\'ll take a look', 'hmbkp' ) . "\n\n" . __( "Kind Regards,\nThe Apologetic BackUpWordPress Backup Emailing Robot", 'hmbkp' ), home_url(), $error_message, 'support@hmn.md' );
|
130 |
+
|
131 |
+
$sent = wp_mail( $this->get_email_address_array(), $subject, $message, $headers );
|
132 |
+
|
133 |
+
return;
|
134 |
+
|
135 |
+
}
|
136 |
+
|
137 |
+
$subject = sprintf( __( 'Backup of %s', 'hmbkp' ), $domain );
|
138 |
+
|
139 |
+
// If it's larger than 10MB assume it's not going to be able to send the backup
|
140 |
+
if ( filesize( $file ) < 1000 * 1000 * 10 ) {
|
141 |
+
|
142 |
+
$message = sprintf( __( 'BackUpWordPress has completed a backup of your site %1$s.', 'hmbkp' ) . "\n\n" . __( 'The backup file should be attached to this email.', 'hmbkp' ) . "\n\n" . __( 'You can download the backup file by clicking the link below:', 'hmbkp' ) . "\n\n" . '%2$s' . "\n\n" . __( "Kind Regards,\nThe Happy BackUpWordPress Backup Emailing Robot", 'hmbkp' ), home_url(), $download );
|
143 |
+
|
144 |
+
$sent = wp_mail( $this->get_email_address_array(), $subject, $message, $headers, $file );
|
145 |
+
|
146 |
+
}
|
147 |
+
|
148 |
+
// If we didn't send the email above then send just the notification
|
149 |
+
if ( ! $sent ) {
|
150 |
+
|
151 |
+
$message = sprintf( __( 'BackUpWordPress has completed a backup of your site %1$s.', 'hmbkp' ) . "\n\n" . __( 'Unfortunately the backup file was too large to attach to this email.', 'hmbkp' ) . "\n\n" . __( 'You can download the backup file by clicking the link below:', 'hmbkp' ) . "\n\n" . '%2$s' . "\n\n" . __( "Kind Regards,\nThe Happy BackUpWordPress Backup Emailing Robot", 'hmbkp' ), home_url(), $download );
|
152 |
+
|
153 |
+
$sent = wp_mail( $this->get_email_address_array(), $subject, $message, $headers );
|
154 |
+
|
155 |
+
}
|
156 |
+
|
157 |
+
}
|
158 |
+
|
159 |
+
}
|
160 |
+
|
161 |
+
}
|
162 |
+
|
163 |
+
// Register the service
|
164 |
+
HMBKP_Services::register( __FILE__, 'HMBKP_Email_Service' );
|
classes/schedule.php
ADDED
@@ -0,0 +1,779 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Extend HM Backup with scheduling and backup file management
|
5 |
+
*
|
6 |
+
* @extends HM_Backup
|
7 |
+
*/
|
8 |
+
class HMBKP_Scheduled_Backup extends HM_Backup {
|
9 |
+
|
10 |
+
/**
|
11 |
+
* The unique schedule id
|
12 |
+
*
|
13 |
+
* @var string
|
14 |
+
* @access private
|
15 |
+
*/
|
16 |
+
private $id = '';
|
17 |
+
|
18 |
+
/**
|
19 |
+
* The slugified version of the schedule name
|
20 |
+
*
|
21 |
+
* @var string
|
22 |
+
* @access private
|
23 |
+
*/
|
24 |
+
private $slug = '';
|
25 |
+
|
26 |
+
/**
|
27 |
+
* The raw schedule options from the database
|
28 |
+
*
|
29 |
+
* @var array
|
30 |
+
* @access private
|
31 |
+
*/
|
32 |
+
private $options = array();
|
33 |
+
|
34 |
+
/**
|
35 |
+
* The unique hook name for this schedule
|
36 |
+
*
|
37 |
+
* @var string
|
38 |
+
* @access private
|
39 |
+
*/
|
40 |
+
private $schedule_hook = '';
|
41 |
+
|
42 |
+
/**
|
43 |
+
* The filepath for the .running file which
|
44 |
+
* is used to track whether a backup is currently in
|
45 |
+
* progress
|
46 |
+
*/
|
47 |
+
private $schedule_running_filepath = '';
|
48 |
+
|
49 |
+
/**
|
50 |
+
* The schedule start time
|
51 |
+
*
|
52 |
+
* (default value: current_time( 'timestamp' ))
|
53 |
+
*
|
54 |
+
* @var mixed
|
55 |
+
* @access private
|
56 |
+
*/
|
57 |
+
private $schedule_start_time = 0;
|
58 |
+
|
59 |
+
/**
|
60 |
+
* Take a file size and return a human readable
|
61 |
+
* version
|
62 |
+
*
|
63 |
+
* @access public
|
64 |
+
* @static
|
65 |
+
* @param int $size
|
66 |
+
* @param string $unit. (default: null)
|
67 |
+
* @param string $format. (default: '%01.2f %s')
|
68 |
+
* @param bool $si. (default: true)
|
69 |
+
* @return int
|
70 |
+
*/
|
71 |
+
public static function human_filesize( $size, $unit = null, $format = '%01.2f %s', $si = true ) {
|
72 |
+
|
73 |
+
// Units
|
74 |
+
if ( $si === true ) :
|
75 |
+
$sizes = array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB' );
|
76 |
+
$mod = 1000;
|
77 |
+
|
78 |
+
else :
|
79 |
+
$sizes = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB');
|
80 |
+
$mod = 1024;
|
81 |
+
|
82 |
+
endif;
|
83 |
+
|
84 |
+
$ii = count( $sizes ) - 1;
|
85 |
+
|
86 |
+
// Max unit
|
87 |
+
$unit = array_search( (string) $unit, $sizes );
|
88 |
+
|
89 |
+
if ( is_null( $unit ) || $unit === false )
|
90 |
+
$unit = $ii;
|
91 |
+
|
92 |
+
// Loop
|
93 |
+
$i = 0;
|
94 |
+
|
95 |
+
while ( $unit != $i && $size >= 1024 && $i < $ii ) {
|
96 |
+
$size /= $mod;
|
97 |
+
$i++;
|
98 |
+
}
|
99 |
+
|
100 |
+
return sprintf( $format, $size, $sizes[$i] );
|
101 |
+
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Setup the schedule object
|
106 |
+
*
|
107 |
+
* Loads the options from the database and populates properties
|
108 |
+
*
|
109 |
+
* @access public
|
110 |
+
* @param string $id
|
111 |
+
*/
|
112 |
+
public function __construct( $id ) {
|
113 |
+
|
114 |
+
// Verify the schedule id
|
115 |
+
if ( ! is_string( $id ) || ! trim( $id ) || ! is_string( $id ) )
|
116 |
+
throw new Exception( 'Argument 1 for ' . __METHOD__ . ' must be a non empty string' );
|
117 |
+
|
118 |
+
// Setup HM Backup
|
119 |
+
parent::__construct();
|
120 |
+
|
121 |
+
// Store id for later
|
122 |
+
$this->id = $id;
|
123 |
+
|
124 |
+
// Load the options
|
125 |
+
$this->options = array_filter( (array) get_option( 'hmbkp_schedule_' . $this->get_id() ) );
|
126 |
+
|
127 |
+
// Setup the schedule hook
|
128 |
+
$this->schedule_hook = 'hmbkp_schedule_' . $this->get_id() . '_hook';
|
129 |
+
|
130 |
+
// Some properties can be overridden with defines
|
131 |
+
if ( defined( 'HMBKP_ROOT' ) && HMBKP_ROOT )
|
132 |
+
$this->set_root( HMBKP_ROOT );
|
133 |
+
|
134 |
+
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH )
|
135 |
+
$this->set_path( HMBKP_PATH );
|
136 |
+
|
137 |
+
if ( defined( 'HMBKP_EXCLUDE' ) && HMBKP_EXCLUDE )
|
138 |
+
parent::set_excludes( HMBKP_EXCLUDE, true );
|
139 |
+
|
140 |
+
if ( defined( 'HMBKP_MYSQLDUMP_PATH' ) )
|
141 |
+
$this->set_mysqldump_command_path( HMBKP_MYSQLDUMP_PATH );
|
142 |
+
|
143 |
+
if ( defined( 'HMBKP_ZIP_PATH' ) )
|
144 |
+
$this->set_zip_command_path( HMBKP_ZIP_PATH );
|
145 |
+
|
146 |
+
if ( defined( 'HMBKP_ZIP_PATH' ) && HMBKP_ZIP_PATH === 'PclZip' && $this->skip_zip_archive = true )
|
147 |
+
$this->set_zip_command_path( false );
|
148 |
+
|
149 |
+
// Set the path - TODO remove external function dependancy
|
150 |
+
$this->set_path( hmbkp_path() );
|
151 |
+
|
152 |
+
// Set the archive filename to site name + schedule slug + date
|
153 |
+
$this->set_archive_filename( implode( '-', array( get_bloginfo( 'name' ), $this->get_id(), $this->get_type(), date( 'Y-m-d-H-i-s', current_time( 'timestamp' ) ) ) ) . '.zip' );
|
154 |
+
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Get the id for this schedule
|
159 |
+
*
|
160 |
+
* @access public
|
161 |
+
*/
|
162 |
+
public function get_id() {
|
163 |
+
return esc_attr( $this->id );
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* Get a slugified version of name
|
168 |
+
*
|
169 |
+
* @access public
|
170 |
+
*/
|
171 |
+
public function get_slug() {
|
172 |
+
|
173 |
+
// We cache slug in $this to save expensive calls to sanitize_title
|
174 |
+
if ( isset( $this->slug ) )
|
175 |
+
return $this->slug;
|
176 |
+
|
177 |
+
return $this->slug = sanitize_title( $this->get_name() );
|
178 |
+
|
179 |
+
}
|
180 |
+
|
181 |
+
/**
|
182 |
+
* Get the name of this backup schedule
|
183 |
+
*
|
184 |
+
* @access public
|
185 |
+
* @return string
|
186 |
+
*/
|
187 |
+
public function get_name() {
|
188 |
+
|
189 |
+
return ucwords( $this->get_type() ) . ' ' . $this->get_reoccurrence();
|
190 |
+
|
191 |
+
}
|
192 |
+
|
193 |
+
/**
|
194 |
+
* Get the type of backup
|
195 |
+
*
|
196 |
+
* @access public
|
197 |
+
* @return string
|
198 |
+
*/
|
199 |
+
public function get_type() {
|
200 |
+
|
201 |
+
if ( empty( $this->options['type'] ) )
|
202 |
+
$this->set_type( 'complete' );
|
203 |
+
|
204 |
+
return $this->options['type'];
|
205 |
+
|
206 |
+
}
|
207 |
+
|
208 |
+
/**
|
209 |
+
* Set the type of backup
|
210 |
+
*
|
211 |
+
* @access public
|
212 |
+
* @param string $type
|
213 |
+
*/
|
214 |
+
public function set_type( $type ) {
|
215 |
+
|
216 |
+
parent::set_type( $type );
|
217 |
+
|
218 |
+
$this->options['type'] = $type;
|
219 |
+
|
220 |
+
$this->clear_filesize_cache();
|
221 |
+
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Get the exclude rules
|
226 |
+
*
|
227 |
+
* @access public
|
228 |
+
* @return array
|
229 |
+
*/
|
230 |
+
public function get_excludes() {
|
231 |
+
|
232 |
+
if ( ! empty( $this->options['excludes'] ) )
|
233 |
+
parent::set_excludes( $this->options['excludes'] );
|
234 |
+
|
235 |
+
return parent::get_excludes();
|
236 |
+
|
237 |
+
}
|
238 |
+
|
239 |
+
/**
|
240 |
+
* Set the exclude rules
|
241 |
+
*
|
242 |
+
* @access public
|
243 |
+
* @param mixed $excludes A comma separated list or array of exclude rules
|
244 |
+
* @param bool $append Whether to replace or append to existing rules
|
245 |
+
* @return string
|
246 |
+
*/
|
247 |
+
public function set_excludes( $excludes, $append = false ) {
|
248 |
+
|
249 |
+
// Use the validation from HM_Backup::set_excludes
|
250 |
+
parent::set_excludes( $excludes, $append );
|
251 |
+
|
252 |
+
// If these are valid excludes and they are different save them
|
253 |
+
if ( parent::get_excludes() && ( empty( $this->options['excludes'] ) || $this->options['excludes'] !== parent::get_excludes() ) ) {
|
254 |
+
|
255 |
+
$this->options['excludes'] = $append && ! empty( $this->options['excludes'] ) ? array_merge( (array) $this->options['excludes'], parent::get_excludes() ) : parent::get_excludes();;
|
256 |
+
|
257 |
+
parent::set_excludes( $this->options['excludes'] );
|
258 |
+
|
259 |
+
$this->clear_filesize_cache();
|
260 |
+
|
261 |
+
}
|
262 |
+
|
263 |
+
}
|
264 |
+
|
265 |
+
/**
|
266 |
+
* Get the maximum number of backups to keep
|
267 |
+
*
|
268 |
+
* @access public
|
269 |
+
*/
|
270 |
+
public function get_max_backups() {
|
271 |
+
|
272 |
+
if ( empty( $this->options['max_backups'] ) )
|
273 |
+
$this->set_max_backups( 10 );
|
274 |
+
|
275 |
+
return (int) esc_attr( $this->options['max_backups'] );
|
276 |
+
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Set the maximum number of backups to keep
|
281 |
+
*
|
282 |
+
* @access public
|
283 |
+
* @param int $max
|
284 |
+
*/
|
285 |
+
public function set_max_backups( $max ) {
|
286 |
+
|
287 |
+
if ( empty( $max ) || ! is_int( $max ) )
|
288 |
+
throw new Exception( 'Argument 1 for ' . __METHOD__ . ' must be a valid integer' );
|
289 |
+
|
290 |
+
$this->options['max_backups'] = $max;
|
291 |
+
|
292 |
+
}
|
293 |
+
|
294 |
+
/**
|
295 |
+
* Get the array of services options for this schedule
|
296 |
+
*
|
297 |
+
* @access public
|
298 |
+
* @return array
|
299 |
+
*/
|
300 |
+
public function get_service_options( $service, $option = null ) {
|
301 |
+
|
302 |
+
if ( ! is_null( $option ) && isset( $this->options[$service][$option] ) )
|
303 |
+
return $this->options[$service][$option];
|
304 |
+
|
305 |
+
if ( isset( $this->options[$service] ) )
|
306 |
+
return $this->options[$service];
|
307 |
+
|
308 |
+
return array();
|
309 |
+
|
310 |
+
}
|
311 |
+
|
312 |
+
/**
|
313 |
+
* Set the service options for this schedule
|
314 |
+
*
|
315 |
+
* @access public
|
316 |
+
*/
|
317 |
+
public function set_service_options( $service, Array $options ) {
|
318 |
+
|
319 |
+
$this->options[$service] = $options;
|
320 |
+
|
321 |
+
}
|
322 |
+
|
323 |
+
/**
|
324 |
+
* Calculate the size of the backup
|
325 |
+
*
|
326 |
+
* Doesn't account for
|
327 |
+
* compression
|
328 |
+
*
|
329 |
+
* @access public
|
330 |
+
* @param bool $cached Whether to return from cache
|
331 |
+
* @return string
|
332 |
+
*/
|
333 |
+
public function get_filesize( $cached = true ) {
|
334 |
+
|
335 |
+
if ( ! $cached || ! $filesize = get_transient( 'hmbkp_schedule_' . $this->get_id() . '_filesize' ) ) {
|
336 |
+
|
337 |
+
$filesize = 0;
|
338 |
+
|
339 |
+
// Don't include database if file only
|
340 |
+
if ( $this->get_type() != 'file' ) {
|
341 |
+
|
342 |
+
global $wpdb;
|
343 |
+
|
344 |
+
$res = $wpdb->get_results( 'SHOW TABLE STATUS FROM `' . DB_NAME . '`', ARRAY_A );
|
345 |
+
|
346 |
+
foreach ( $res as $r )
|
347 |
+
$filesize += (float) $r['Data_length'];
|
348 |
+
|
349 |
+
}
|
350 |
+
|
351 |
+
// Don't include files if database only
|
352 |
+
if ( $this->get_type() != 'database' ) {
|
353 |
+
|
354 |
+
// Get rid of any cached filesizes
|
355 |
+
clearstatcache();
|
356 |
+
|
357 |
+
$excludes = $this->exclude_string( 'regex' );
|
358 |
+
|
359 |
+
foreach ( $this->get_files() as $file ) {
|
360 |
+
|
361 |
+
if ( $file === '.' || $file === '..' || ! $file->isReadable() )
|
362 |
+
continue;
|
363 |
+
|
364 |
+
// Excludes
|
365 |
+
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', $this->conform_dir( $file->getPathname() ) ) ) )
|
366 |
+
continue;
|
367 |
+
|
368 |
+
$filesize += (float) $file->getSize();
|
369 |
+
|
370 |
+
}
|
371 |
+
|
372 |
+
}
|
373 |
+
|
374 |
+
// Cache for a day
|
375 |
+
set_transient( 'hmbkp_schedule_' . $this->get_id() . '_filesize', $filesize, time() + 60 * 60 * 24 );
|
376 |
+
|
377 |
+
}
|
378 |
+
|
379 |
+
return self::human_filesize( $filesize, null, '%01u %s' );
|
380 |
+
|
381 |
+
}
|
382 |
+
|
383 |
+
/**
|
384 |
+
* Check whether the filesize has already been calculated and cached.
|
385 |
+
*
|
386 |
+
* @access public
|
387 |
+
* @return void
|
388 |
+
*/
|
389 |
+
public function is_filesize_cached() {
|
390 |
+
return (bool) get_transient( 'hmbkp_schedule_' . $this->get_id() . '_filesize' );
|
391 |
+
}
|
392 |
+
|
393 |
+
/**
|
394 |
+
* Clear the cached filesize, forces the filesize to be re-calculated the next
|
395 |
+
* time get_filesize is called
|
396 |
+
*
|
397 |
+
* @access public
|
398 |
+
* @return void
|
399 |
+
*/
|
400 |
+
public function clear_filesize_cache() {
|
401 |
+
delete_transient( 'hmbkp_schedule_' . $this->get_id() . '_filesize' );
|
402 |
+
}
|
403 |
+
|
404 |
+
/**
|
405 |
+
* Get the start time for the schedule
|
406 |
+
*
|
407 |
+
* @access public
|
408 |
+
* @return int timestamp || 0 for manual only schedules
|
409 |
+
*/
|
410 |
+
public function get_schedule_start_time() {
|
411 |
+
|
412 |
+
if ( $this->get_reoccurrence() === 'manually' )
|
413 |
+
return 0;
|
414 |
+
|
415 |
+
if ( ! $this->schedule_start_time )
|
416 |
+
$this->set_schedule_start_time( current_time( 'timestamp' ) );
|
417 |
+
|
418 |
+
return $this->schedule_start_time;
|
419 |
+
|
420 |
+
}
|
421 |
+
|
422 |
+
/**
|
423 |
+
* Set the schedule start time.
|
424 |
+
*
|
425 |
+
* @access public
|
426 |
+
* @param int $timestamp
|
427 |
+
* @return void
|
428 |
+
*/
|
429 |
+
public function set_schedule_start_time( $timestamp ) {
|
430 |
+
|
431 |
+
if ( (string) (int) $timestamp !== (string) $timestamp )
|
432 |
+
throw new Exception( 'Argument 1 for ' . __METHOD__ . ' must be a valid UNIX timestamp' );
|
433 |
+
|
434 |
+
$this->schedule_start_time = $timestamp;
|
435 |
+
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* Get the schedule reoccurrence
|
440 |
+
*
|
441 |
+
* @access public
|
442 |
+
*/
|
443 |
+
public function get_reoccurrence() {
|
444 |
+
|
445 |
+
// Default to no reoccurrence
|
446 |
+
if ( empty( $this->options['reoccurrence'] ) )
|
447 |
+
$this->set_reoccurrence( 'manually' );
|
448 |
+
|
449 |
+
return esc_attr( $this->options['reoccurrence'] );
|
450 |
+
|
451 |
+
}
|
452 |
+
|
453 |
+
/**
|
454 |
+
* Set the schedule reoccurrence
|
455 |
+
*
|
456 |
+
* @access public
|
457 |
+
* @param string $reoccurrence
|
458 |
+
*/
|
459 |
+
public function set_reoccurrence( $reoccurrence ) {
|
460 |
+
|
461 |
+
// Check it's valid
|
462 |
+
if ( ! is_string( $reoccurrence ) || ! trim( $reoccurrence ) || ( ! in_array( $reoccurrence, array_keys( wp_get_schedules() ) ) ) && $reoccurrence !== 'manually' )
|
463 |
+
throw new Exception( 'Argument 1 for ' . __METHOD__ . ' must be a valid cron reoccurrence or "manually"' );
|
464 |
+
|
465 |
+
if ( isset( $this->options['reoccurrence'] ) && $this->options['reoccurrence'] === $reoccurrence )
|
466 |
+
return;
|
467 |
+
|
468 |
+
$this->options['reoccurrence'] = $reoccurrence;
|
469 |
+
|
470 |
+
if ( $reoccurrence === 'manually' )
|
471 |
+
$this->unschedule();
|
472 |
+
|
473 |
+
else
|
474 |
+
$this->schedule();
|
475 |
+
|
476 |
+
}
|
477 |
+
|
478 |
+
/**
|
479 |
+
* Get the interval between backups
|
480 |
+
*
|
481 |
+
* @access public
|
482 |
+
* @return int
|
483 |
+
*/
|
484 |
+
public function get_interval() {
|
485 |
+
|
486 |
+
$schedules = wp_get_schedules();
|
487 |
+
|
488 |
+
if ( $this->get_reoccurrence() === 'manually' )
|
489 |
+
return 0;
|
490 |
+
|
491 |
+
return $schedules[$this->get_reoccurrence()]['interval'];
|
492 |
+
|
493 |
+
}
|
494 |
+
|
495 |
+
/**
|
496 |
+
* Get the next occurrence of this scheduled backup
|
497 |
+
*
|
498 |
+
* @access public
|
499 |
+
*/
|
500 |
+
public function get_next_occurrence() {
|
501 |
+
|
502 |
+
return wp_next_scheduled( $this->schedule_hook );
|
503 |
+
|
504 |
+
}
|
505 |
+
|
506 |
+
private function get_schedule_running_path() {
|
507 |
+
return $this->get_path() . '/.schedule-' . $this->get_id() . '-running';
|
508 |
+
}
|
509 |
+
|
510 |
+
/**
|
511 |
+
* Schedule the cron
|
512 |
+
*
|
513 |
+
* @access public
|
514 |
+
*/
|
515 |
+
public function schedule() {
|
516 |
+
|
517 |
+
// Clear any existing hooks
|
518 |
+
$this->unschedule();
|
519 |
+
|
520 |
+
wp_schedule_event( $this->get_schedule_start_time() + $this->get_interval(), $this->get_reoccurrence(), $this->schedule_hook );
|
521 |
+
|
522 |
+
// Hook the backu into the schedule hook
|
523 |
+
add_action( $this->schedule_hook, array( $this, 'run' ) );
|
524 |
+
|
525 |
+
}
|
526 |
+
|
527 |
+
public function unschedule() {
|
528 |
+
wp_clear_scheduled_hook( $this->schedule_hook );
|
529 |
+
}
|
530 |
+
|
531 |
+
/**
|
532 |
+
* Run the backup
|
533 |
+
*
|
534 |
+
* @access public
|
535 |
+
*/
|
536 |
+
public function run() {
|
537 |
+
|
538 |
+
// Mark the backup as started
|
539 |
+
$this->set_status( __( 'Backup started', 'hmbkp' ) );
|
540 |
+
|
541 |
+
$this->backup();
|
542 |
+
|
543 |
+
// Delete the backup running file
|
544 |
+
if ( file_exists( $this->get_schedule_running_path() ) )
|
545 |
+
unlink( $this->get_schedule_running_path() );
|
546 |
+
|
547 |
+
$this->delete_old_backups();
|
548 |
+
|
549 |
+
}
|
550 |
+
|
551 |
+
/**
|
552 |
+
* Get the status of the running backup.
|
553 |
+
*
|
554 |
+
* @access public
|
555 |
+
* @return string
|
556 |
+
*/
|
557 |
+
public function get_status() {
|
558 |
+
|
559 |
+
if ( ! file_exists( $this->get_schedule_running_path() ) )
|
560 |
+
return '';
|
561 |
+
|
562 |
+
return end( explode( '::', file_get_contents( $this->get_schedule_running_path() ) ) );
|
563 |
+
|
564 |
+
}
|
565 |
+
|
566 |
+
/**
|
567 |
+
* Get the filename that the running status is stored in.
|
568 |
+
*
|
569 |
+
* @access public
|
570 |
+
* @return string
|
571 |
+
*/
|
572 |
+
public function get_running_backup_filename() {
|
573 |
+
|
574 |
+
if ( ! file_exists( $this->get_schedule_running_path() ) )
|
575 |
+
return '';
|
576 |
+
|
577 |
+
return reset( explode( '::', file_get_contents( $this->get_schedule_running_path() ) ) );
|
578 |
+
}
|
579 |
+
|
580 |
+
/**
|
581 |
+
* Set the status of the running backup
|
582 |
+
*
|
583 |
+
* @access public
|
584 |
+
* @param string $message
|
585 |
+
* @return void
|
586 |
+
*/
|
587 |
+
protected function set_status( $message ) {
|
588 |
+
|
589 |
+
if ( ! $handle = fopen( $this->get_schedule_running_path(), 'w' ) )
|
590 |
+
return;
|
591 |
+
|
592 |
+
fwrite( $handle, $this->get_archive_filename() . '::' . $message );
|
593 |
+
|
594 |
+
fclose( $handle );
|
595 |
+
|
596 |
+
}
|
597 |
+
|
598 |
+
/**
|
599 |
+
* Hook into the actions fired in HM Backup and set the status
|
600 |
+
*
|
601 |
+
* @return null
|
602 |
+
*/
|
603 |
+
protected function do_action( $action ) {
|
604 |
+
|
605 |
+
switch ( $action ) :
|
606 |
+
|
607 |
+
case 'hmbkp_archive_started' :
|
608 |
+
|
609 |
+
$this->set_status( __( 'Creating zip archive', 'hmbkp' ) );
|
610 |
+
|
611 |
+
break;
|
612 |
+
|
613 |
+
case 'hmbkp_mysqldump_started' :
|
614 |
+
|
615 |
+
$this->set_status( __( 'Dumping database', 'hmbkp' ) );
|
616 |
+
|
617 |
+
break;
|
618 |
+
|
619 |
+
case 'hmbkp_backup_complete' :
|
620 |
+
|
621 |
+
if ( $this->get_errors() ) {
|
622 |
+
|
623 |
+
$file = $this->get_path() . '/.backup_errors';
|
624 |
+
|
625 |
+
if ( file_exists( $file ) )
|
626 |
+
unlink( $file );
|
627 |
+
|
628 |
+
if ( ! $handle = @fopen( $file, 'w' ) )
|
629 |
+
return;
|
630 |
+
|
631 |
+
fwrite( $handle, json_encode( $this->get_errors() ) );
|
632 |
+
|
633 |
+
fclose( $handle );
|
634 |
+
|
635 |
+
}
|
636 |
+
|
637 |
+
if ( $this->get_warnings() ) {
|
638 |
+
|
639 |
+
$file = $this->get_path() . '/.backup_warnings';
|
640 |
+
|
641 |
+
if ( file_exists( $file ) )
|
642 |
+
unlink( $file );
|
643 |
+
|
644 |
+
if ( ! $handle = @fopen( $file, 'w' ) )
|
645 |
+
return;
|
646 |
+
|
647 |
+
fwrite( $handle, json_encode( $this->get_warnings() ) );
|
648 |
+
|
649 |
+
fclose( $handle );
|
650 |
+
|
651 |
+
}
|
652 |
+
|
653 |
+
break;
|
654 |
+
|
655 |
+
endswitch;
|
656 |
+
|
657 |
+
// Pass the actions to all the services
|
658 |
+
foreach ( HMBKP_Services::get_services( $this ) as $service )
|
659 |
+
$service->action( $action );
|
660 |
+
|
661 |
+
// Fire the parent function as well
|
662 |
+
parent::do_action( $action );
|
663 |
+
|
664 |
+
}
|
665 |
+
|
666 |
+
/**
|
667 |
+
* Get the backups created by this schedule
|
668 |
+
*
|
669 |
+
* @todo look into using recursiveDirectoryIterator and recursiveRegexIterator
|
670 |
+
* @access public
|
671 |
+
*/
|
672 |
+
public function get_backups() {
|
673 |
+
|
674 |
+
$files = array();
|
675 |
+
|
676 |
+
if ( $handle = @opendir( $this->get_path() ) ) {
|
677 |
+
|
678 |
+
while ( false !== ( $file = readdir( $handle ) ) )
|
679 |
+
if ( pathinfo( $file, PATHINFO_EXTENSION ) === 'zip' && strpos( $file, $this->get_id() ) !== false && $this->get_running_backup_filename() != $file )
|
680 |
+
$files[@filemtime( trailingslashit( $this->get_path() ) . $file )] = trailingslashit( $this->get_path() ) . $file;
|
681 |
+
|
682 |
+
closedir( $handle );
|
683 |
+
|
684 |
+
}
|
685 |
+
|
686 |
+
krsort( $files );
|
687 |
+
|
688 |
+
return $files;
|
689 |
+
|
690 |
+
}
|
691 |
+
|
692 |
+
/**
|
693 |
+
* Delete old backups
|
694 |
+
*
|
695 |
+
* @access private
|
696 |
+
*/
|
697 |
+
public function delete_old_backups() {
|
698 |
+
|
699 |
+
if ( count( $this->get_backups() ) <= $this->get_max_backups() )
|
700 |
+
return;
|
701 |
+
|
702 |
+
array_map( array( $this, 'delete_backup' ), array_slice( $this->get_backups(), $this->get_max_backups() ) );
|
703 |
+
|
704 |
+
}
|
705 |
+
|
706 |
+
/**
|
707 |
+
* Delete a specific back up file created by this schedule
|
708 |
+
*
|
709 |
+
* @access public
|
710 |
+
* @param string $filepath
|
711 |
+
*/
|
712 |
+
public function delete_backup( $filepath ) {
|
713 |
+
|
714 |
+
// Check that it's a valid filepath
|
715 |
+
if ( empty( $filepath ) || ! is_string( $filepath ) )
|
716 |
+
throw new Exception( 'Argument 1 for ' . __METHOD__ . ' must be a non empty string' );
|
717 |
+
|
718 |
+
// Make sure it exists
|
719 |
+
if ( ! file_exists( $filepath ) )
|
720 |
+
throw new Exception( $filepath . ' doesn\'t exist' );
|
721 |
+
|
722 |
+
// Make sure it was created by this schedule
|
723 |
+
if ( strpos( $filepath, $this->get_id() ) === false )
|
724 |
+
throw new Exception( 'That backup wasn\'t created by this schedule' );
|
725 |
+
|
726 |
+
unlink( $filepath );
|
727 |
+
|
728 |
+
}
|
729 |
+
|
730 |
+
/**
|
731 |
+
* Delete all back up files created by this schedule
|
732 |
+
*
|
733 |
+
* @access public
|
734 |
+
*/
|
735 |
+
public function delete_backups() {
|
736 |
+
|
737 |
+
array_map( array( $this, 'delete_backup' ), $this->get_backups() );
|
738 |
+
|
739 |
+
}
|
740 |
+
|
741 |
+
/**
|
742 |
+
* Save the schedules options.
|
743 |
+
*
|
744 |
+
* @access public
|
745 |
+
*/
|
746 |
+
public function save() {
|
747 |
+
|
748 |
+
// Only save them if they have changed
|
749 |
+
if ( $this->options !== get_option( 'hmbkp_schedule_' . $this->get_id() ) )
|
750 |
+
update_option( 'hmbkp_schedule_' . $this->get_id(), $this->options );
|
751 |
+
|
752 |
+
}
|
753 |
+
|
754 |
+
/**
|
755 |
+
* Cancel this schedule
|
756 |
+
*
|
757 |
+
* Cancels the cron job, removes the schedules options
|
758 |
+
* and optionally deletes all backups crated by
|
759 |
+
* this schedule.
|
760 |
+
*
|
761 |
+
* @access public
|
762 |
+
*/
|
763 |
+
public function cancel() {
|
764 |
+
|
765 |
+
// Delete the schedule options
|
766 |
+
delete_option( 'hmbkp_schedule_' . $this->get_id() );
|
767 |
+
|
768 |
+
// Clear any existing schedules
|
769 |
+
$this->unschedule();
|
770 |
+
|
771 |
+
// Clear the filesize transient
|
772 |
+
$this->clear_filesize_cache();
|
773 |
+
|
774 |
+
// Delete it's backups
|
775 |
+
$this->delete_backups();
|
776 |
+
|
777 |
+
}
|
778 |
+
|
779 |
+
}
|
classes/schedules.php
ADDED
@@ -0,0 +1,56 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* A simple class for loading schedules
|
5 |
+
*/
|
6 |
+
class HMBKP_Schedules {
|
7 |
+
|
8 |
+
/**
|
9 |
+
* An array of schedules
|
10 |
+
*
|
11 |
+
* @var mixed
|
12 |
+
* @access private
|
13 |
+
*/
|
14 |
+
private $schedules;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Load the schedules from wp_options and store in $this->schedules
|
18 |
+
*
|
19 |
+
* @access public
|
20 |
+
*/
|
21 |
+
public function __construct() {
|
22 |
+
|
23 |
+
global $wpdb;
|
24 |
+
|
25 |
+
// Load all schedule options from the database
|
26 |
+
$schedules = $wpdb->get_col( "SELECT option_name from $wpdb->options WHERE option_name LIKE 'hmbkp\_schedule\_%'" );
|
27 |
+
|
28 |
+
// Instantiate each one as a HMBKP_Scheduled_Backup
|
29 |
+
$this->schedules = array_map( array( $this, 'instantiate' ), array_filter( (array) $schedules ) );
|
30 |
+
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Get an array of schedules
|
35 |
+
*
|
36 |
+
* @access public
|
37 |
+
* @return array
|
38 |
+
*/
|
39 |
+
public function get_schedules() {
|
40 |
+
return $this->schedules;
|
41 |
+
}
|
42 |
+
|
43 |
+
/**
|
44 |
+
* Instantiate the individual scheduled backup objects
|
45 |
+
*
|
46 |
+
* @access private
|
47 |
+
* @param string $id
|
48 |
+
* @return array An array of HMBKP_Scheduled_Backup objects
|
49 |
+
*/
|
50 |
+
private function instantiate( $id ) {
|
51 |
+
|
52 |
+
return new HMBKP_Scheduled_Backup( str_replace( 'hmbkp_schedule_', '', $id ) );
|
53 |
+
|
54 |
+
}
|
55 |
+
|
56 |
+
}
|
classes/services.php
ADDED
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* An abstract service class, individual services should
|
5 |
+
* extend this class
|
6 |
+
*/
|
7 |
+
abstract class HMBKP_Service {
|
8 |
+
|
9 |
+
/**
|
10 |
+
* The instance HMBKP_Backup_Schedule that this service is
|
11 |
+
* is currently working with
|
12 |
+
*/
|
13 |
+
protected $schedule;
|
14 |
+
|
15 |
+
/**
|
16 |
+
* The form to output as part of the schedule settings
|
17 |
+
*
|
18 |
+
* If you don't want a whole form return ''; here and use @field instead
|
19 |
+
*/
|
20 |
+
abstract protected function form();
|
21 |
+
|
22 |
+
/**
|
23 |
+
* The field to output as part of the schedule settings
|
24 |
+
*
|
25 |
+
* If you don't want a field return ''; here and use @field instead
|
26 |
+
*/
|
27 |
+
abstract protected function field();
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Validate and sanitize data before it's saved.
|
31 |
+
*
|
32 |
+
* @param array &$new_data An array or data from $_GET, passed by reference so it can be modified,
|
33 |
+
* @param array $old_data The old data thats going to be overwritten
|
34 |
+
* @return array $error Array of validation errors e.g. return array( 'email' => 'not valid' );
|
35 |
+
*/
|
36 |
+
abstract protected function update( &$new_data, $old_data );
|
37 |
+
|
38 |
+
/**
|
39 |
+
* The string to be output as part of the schedule sentence
|
40 |
+
*
|
41 |
+
* @return string
|
42 |
+
*/
|
43 |
+
abstract protected function display();
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Receives actions from the backup
|
47 |
+
*
|
48 |
+
* This is where the service should do it's thing
|
49 |
+
*
|
50 |
+
* @see HM_Backup::do_action for a list of the actions
|
51 |
+
*/
|
52 |
+
abstract protected function action( $action );
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Utility for getting a formated html input name attribute
|
56 |
+
*
|
57 |
+
* @param string $name The name of the field
|
58 |
+
* @return string The formated name
|
59 |
+
*/
|
60 |
+
protected function get_field_name( $name ) {
|
61 |
+
return esc_attr( get_class( $this ) . '[' . $name . ']' );
|
62 |
+
}
|
63 |
+
|
64 |
+
/**
|
65 |
+
* Get the value of a field
|
66 |
+
* @param string $name The name of the field
|
67 |
+
* @return string The field value
|
68 |
+
*/
|
69 |
+
protected function get_field_value( $name, $esc = 'esc_attr' ) {
|
70 |
+
|
71 |
+
if ( $this->schedule->get_service_options( get_class( $this ), $name ) )
|
72 |
+
return $esc( $this->schedule->get_service_options( get_class( $this ), $name ) );
|
73 |
+
|
74 |
+
return '';
|
75 |
+
|
76 |
+
}
|
77 |
+
|
78 |
+
/**
|
79 |
+
* Save the settings for this service
|
80 |
+
*
|
81 |
+
* @return null|array returns null on success, array of errors on failure
|
82 |
+
*/
|
83 |
+
public function save() {
|
84 |
+
|
85 |
+
$classname = get_class( $this );
|
86 |
+
|
87 |
+
$old_data = $this->schedule->get_service_options( $classname );
|
88 |
+
|
89 |
+
$new_data = isset( $_GET[$classname] ) ? $_GET[$classname] : $old_data;
|
90 |
+
|
91 |
+
$errors = $this->update( $new_data, $old_data );
|
92 |
+
|
93 |
+
if ( $errors = array_flip( $errors ) ) {
|
94 |
+
|
95 |
+
foreach( $errors as $error => &$field )
|
96 |
+
$field = get_class( $this ) . '[' . $field . ']';
|
97 |
+
|
98 |
+
return array_flip( $errors );
|
99 |
+
|
100 |
+
}
|
101 |
+
|
102 |
+
$this->schedule->set_service_options( $classname, $new_data );
|
103 |
+
|
104 |
+
return array();
|
105 |
+
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Set the current schedule object
|
110 |
+
*
|
111 |
+
* @param HMBKP_Scheduled_Backup $schedule An instantiated schedule object
|
112 |
+
*/
|
113 |
+
public function set_schedule( HMBKP_Scheduled_Backup $schedule ) {
|
114 |
+
$this->schedule = $schedule;
|
115 |
+
}
|
116 |
+
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* A singleton to handle the registering, unregistering
|
121 |
+
* and storage of services
|
122 |
+
*/
|
123 |
+
class HMBKP_Services {
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Store the current instance
|
127 |
+
*
|
128 |
+
* @access private
|
129 |
+
* @var object HMBKP_Services
|
130 |
+
* @static
|
131 |
+
*/
|
132 |
+
private static $instance;
|
133 |
+
|
134 |
+
/**
|
135 |
+
* The array of services
|
136 |
+
*
|
137 |
+
* Should be of the format array( __FILE__ => __CLASS__ );
|
138 |
+
*
|
139 |
+
* @access private
|
140 |
+
* @var array
|
141 |
+
* @static
|
142 |
+
*/
|
143 |
+
private $services = array();
|
144 |
+
|
145 |
+
/**
|
146 |
+
* The current schedule object
|
147 |
+
*
|
148 |
+
* @access private
|
149 |
+
* @var object HMBKP_Scheduled_Backup
|
150 |
+
*/
|
151 |
+
private $schedule;
|
152 |
+
|
153 |
+
/**
|
154 |
+
* Get the current instance
|
155 |
+
*
|
156 |
+
* @access public
|
157 |
+
* @static
|
158 |
+
*/
|
159 |
+
public static function instance() {
|
160 |
+
|
161 |
+
if ( ! isset( self::$instance ) )
|
162 |
+
self::$instance = new HMBKP_Services;
|
163 |
+
|
164 |
+
return self::$instance;
|
165 |
+
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Get the array of registered services
|
170 |
+
*
|
171 |
+
* @access public
|
172 |
+
*/
|
173 |
+
public function get_services( HMBKP_Scheduled_Backup $schedule = null ) {
|
174 |
+
|
175 |
+
if ( is_null( $schedule ) )
|
176 |
+
return self::instance()->services;
|
177 |
+
|
178 |
+
self::instance()->schedule = $schedule;
|
179 |
+
|
180 |
+
return array_map( array( self::instance(), 'instantiate' ), self::instance()->services );
|
181 |
+
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* Register a new service
|
186 |
+
*
|
187 |
+
* @access public
|
188 |
+
*/
|
189 |
+
public function register( $filepath, $classname ) {
|
190 |
+
|
191 |
+
if ( ! file_exists( $filepath ) )
|
192 |
+
throw new Exception( 'Argument 1 for ' . __METHOD__ . ' must be a valid filepath' );
|
193 |
+
|
194 |
+
self::instance()->services[$filepath] = $classname;
|
195 |
+
|
196 |
+
}
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Unregister an existing service
|
200 |
+
*
|
201 |
+
* @access public
|
202 |
+
*/
|
203 |
+
public function unregister( $filepath ) {
|
204 |
+
|
205 |
+
if ( ! isset( self::instance()->services[$filepath] ) )
|
206 |
+
throw new Exception( 'Argument 1 for ' . __METHOD__ . ' must be a registered service' );
|
207 |
+
|
208 |
+
unset( self::instance()->services[$filepath] );
|
209 |
+
|
210 |
+
}
|
211 |
+
|
212 |
+
/**
|
213 |
+
* Instantiate the individual service classes
|
214 |
+
*
|
215 |
+
* @access private
|
216 |
+
* @param string $class
|
217 |
+
* @return array An array of instantiated classes
|
218 |
+
*/
|
219 |
+
private function instantiate( $class ) {
|
220 |
+
|
221 |
+
if ( ! class_exists( $class ) )
|
222 |
+
throw new Exception( 'Argument 1 for ' . __METHOD__ . ' must be a valid class' );
|
223 |
+
|
224 |
+
$$class = new $class;
|
225 |
+
|
226 |
+
if ( self::instance()->schedule )
|
227 |
+
$$class->set_schedule( self::instance()->schedule );
|
228 |
+
|
229 |
+
return $$class;
|
230 |
+
|
231 |
+
}
|
232 |
+
|
233 |
+
}
|
classes/wp-cli.php
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Implement backup command
|
5 |
+
*
|
6 |
+
* @todo fix
|
7 |
+
* @package wp-cli
|
8 |
+
* @subpackage commands/third-party
|
9 |
+
*/
|
10 |
+
class BackUpCommand extends WP_CLI_Command {
|
11 |
+
|
12 |
+
public function __construct( $args, $assoc_args ) {
|
13 |
+
|
14 |
+
// Make sure it's possible to do a backup
|
15 |
+
if ( HM_Backup::is_safe_mode_active() ) {
|
16 |
+
WP_CLI::error( __( 'Backup not possible when php is running safe_mode on', 'hmbkp' ) );
|
17 |
+
return false;
|
18 |
+
}
|
19 |
+
|
20 |
+
add_action( 'hmbkp_mysqldump_started', function() {
|
21 |
+
WP_CLI::line( __( 'Backup: Dumping database...', 'hmbkp' ) );
|
22 |
+
} );
|
23 |
+
|
24 |
+
add_action( 'hmbkp_archive_started', function() {
|
25 |
+
WP_CLI::line( __( 'Backup: Zipping everything up...', 'hmbkp' ) );
|
26 |
+
} );
|
27 |
+
|
28 |
+
// Clean up any mess left by a previous backup
|
29 |
+
hmbkp_cleanup();
|
30 |
+
|
31 |
+
$hm_backup = new HM_Backup();
|
32 |
+
|
33 |
+
if ( ! empty( $assoc_args['path'] ) )
|
34 |
+
$hm_backup->set_path( $assoc_args['path'] );
|
35 |
+
|
36 |
+
if ( ! empty( $assoc_args['root'] ) )
|
37 |
+
$hm_backup->set_root( $assoc_args['root'] );
|
38 |
+
|
39 |
+
if ( ( ! is_dir( $hm_backup->get_path() ) && ( ! is_writable( dirname( $hm_backup->get_path() ) ) || ! mkdir( $hm_backup->get_path() ) ) ) || ! is_writable( $hm_backup->get_path() ) ) {
|
40 |
+
WP_CLI::error( __( 'Invalid backup path', 'hmbkp' ) );
|
41 |
+
return false;
|
42 |
+
}
|
43 |
+
|
44 |
+
if ( ! is_dir( $hm_backup->get_root() ) || ! is_readable( $hm_backup->get_root() ) ) {
|
45 |
+
WP_CLI::error( __( 'Invalid root path', 'hmbkp' ) );
|
46 |
+
return false;
|
47 |
+
}
|
48 |
+
|
49 |
+
if ( ! empty( $assoc_args['files_only'] ) )
|
50 |
+
$hm_backup->set_type( 'file' );
|
51 |
+
|
52 |
+
if ( ! empty( $assoc_args['database_only'] ) )
|
53 |
+
$hm_backup->set_type( 'database' );
|
54 |
+
|
55 |
+
if ( isset( $assoc_args['mysqldump_command_path'] ) )
|
56 |
+
$hm_backup->set_mysqldump_command_path( $assoc_args['mysqldump_command_path'] );
|
57 |
+
|
58 |
+
if ( isset( $assoc_args['zip_command_path'] ) )
|
59 |
+
$hm_backup->set_zip_command_path( $assoc_args['zip_command_path'] );
|
60 |
+
|
61 |
+
if ( ! empty( $assoc_args['excludes'] ) )
|
62 |
+
$hm_backup->set_excludes( $assoc_args['excludes'] );
|
63 |
+
|
64 |
+
$hm_backup->backup();
|
65 |
+
|
66 |
+
// Delete any old backup files
|
67 |
+
//hmbkp_delete_old_backups();
|
68 |
+
|
69 |
+
if ( file_exists( $hm_backup->get_archive_filepath() ) )
|
70 |
+
WP_CLI::success( __( 'Backup Complete: ', 'hmbkp' ) . $hm_backup->get_archive_filepath() );
|
71 |
+
|
72 |
+
else
|
73 |
+
WP_CLI::error( __( 'Backup Failed', 'hmbkp' ) );
|
74 |
+
|
75 |
+
}
|
76 |
+
|
77 |
+
static function help() {
|
78 |
+
|
79 |
+
WP_CLI::line( <<<EOB
|
80 |
+
usage: wp backup [--files_only] [--database_only] [--path<dir>] [--root<dir>] [--zip_command_path=<path>] [--mysqldump_command_path=<path>]
|
81 |
+
|
82 |
+
--files_only Backup files only, default to off
|
83 |
+
--database_only Backup database only, defaults to off
|
84 |
+
--path dir that the backup should be save in, defaults to wp-content/backups/
|
85 |
+
--root dir that should be backed up, defaults to site root.
|
86 |
+
--zip_command_path path to your zip binary, standard locations are automatically used
|
87 |
+
--mysqldump_command_path path to your mysqldump binary, standard locations are automatically used
|
88 |
+
|
89 |
+
EOB
|
90 |
+
);
|
91 |
+
|
92 |
+
}
|
93 |
+
|
94 |
+
}
|
95 |
+
WP_CLI::addCommand( 'backup', 'BackUpCommand' );
|
functions/backup.actions.php
DELETED
@@ -1,61 +0,0 @@
|
|
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' );
|
25 |
-
|
26 |
-
function hmbkp_backup_complete( $backup ) {
|
27 |
-
|
28 |
-
if ( $backup->errors() ) {
|
29 |
-
|
30 |
-
hmbkp_cleanup();
|
31 |
-
|
32 |
-
$file = hmbkp_path() . '/.backup_errors';
|
33 |
-
|
34 |
-
if ( file_exists( $file ) )
|
35 |
-
unlink( $file );
|
36 |
-
|
37 |
-
if ( ! $handle = @fopen( $file, 'w' ) )
|
38 |
-
return;
|
39 |
-
|
40 |
-
fwrite( $handle, json_encode( $backup->errors() ) );
|
41 |
-
|
42 |
-
fclose( $handle );
|
43 |
-
|
44 |
-
} elseif ( $backup->warnings() ) {
|
45 |
-
|
46 |
-
$file = hmbkp_path() . '/.backup_warnings';
|
47 |
-
|
48 |
-
if ( file_exists( $file ) )
|
49 |
-
unlink( $file );
|
50 |
-
|
51 |
-
if ( ! $handle = @fopen( $file, 'w' ) )
|
52 |
-
return;
|
53 |
-
|
54 |
-
fwrite( $handle, json_encode( $backup->warnings() ) );
|
55 |
-
|
56 |
-
fclose( $handle );
|
57 |
-
|
58 |
-
}
|
59 |
-
|
60 |
-
}
|
61 |
-
add_action( 'hmbkp_backup_complete', 'hmbkp_backup_complete' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
functions/backup.functions.php
DELETED
@@ -1,294 +0,0 @@
|
|
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 a previous backup
|
15 |
-
hmbkp_cleanup();
|
16 |
-
|
17 |
-
HM_Backup::get_instance()->backup();
|
18 |
-
|
19 |
-
hmbkp_set_status( __( 'Removing old backups', 'hmbkp' ) );
|
20 |
-
|
21 |
-
// Delete any old backup files
|
22 |
-
hmbkp_delete_old_backups();
|
23 |
-
|
24 |
-
if ( file_exists( hmbkp_path() . '/.backup_running' ) )
|
25 |
-
unlink( hmbkp_path() . '/.backup_running' );
|
26 |
-
|
27 |
-
if ( file_exists( HM_Backup::get_instance()->archive_filepath() ) ) {
|
28 |
-
|
29 |
-
$file = hmbkp_path() . '/.backup_complete';
|
30 |
-
|
31 |
-
if ( ! $handle = @fopen( $file, 'w' ) )
|
32 |
-
return;
|
33 |
-
|
34 |
-
fwrite( $handle, HM_Backup::get_instance()->archive_filename() );
|
35 |
-
|
36 |
-
fclose( $handle );
|
37 |
-
|
38 |
-
}
|
39 |
-
|
40 |
-
hmbkp_email_backup();
|
41 |
-
|
42 |
-
}
|
43 |
-
|
44 |
-
/**
|
45 |
-
* Deletes old backup files
|
46 |
-
*
|
47 |
-
* @return null
|
48 |
-
*/
|
49 |
-
function hmbkp_delete_old_backups() {
|
50 |
-
|
51 |
-
$files = hmbkp_get_backups();
|
52 |
-
|
53 |
-
if ( count( $files ) <= hmbkp_max_backups() )
|
54 |
-
return;
|
55 |
-
|
56 |
-
foreach( array_slice( $files, hmbkp_max_backups() ) as $file )
|
57 |
-
hmbkp_delete_backup( base64_encode( $file ) );
|
58 |
-
|
59 |
-
}
|
60 |
-
|
61 |
-
/**
|
62 |
-
* Returns an array of backup files
|
63 |
-
*
|
64 |
-
* @todo use RecursiveDirectoryIterator
|
65 |
-
* @return array $files
|
66 |
-
*/
|
67 |
-
function hmbkp_get_backups() {
|
68 |
-
|
69 |
-
$files = array();
|
70 |
-
|
71 |
-
$hmbkp_path = hmbkp_path();
|
72 |
-
|
73 |
-
if ( $handle = @opendir( $hmbkp_path ) ) :
|
74 |
-
|
75 |
-
while ( false !== ( $file = readdir( $handle ) ) )
|
76 |
-
if ( end( explode( '.', $file ) ) == 'zip' )
|
77 |
-
$files[@filemtime( trailingslashit( $hmbkp_path ) . $file )] = trailingslashit( $hmbkp_path ) . $file;
|
78 |
-
|
79 |
-
closedir( $handle );
|
80 |
-
|
81 |
-
endif;
|
82 |
-
|
83 |
-
// If there is a custom backups directory and it's not writable then include those backups as well
|
84 |
-
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH && is_dir( HMBKP_PATH ) && ! is_writable( HMBKP_PATH ) ) :
|
85 |
-
|
86 |
-
if ( $handle = opendir( HMBKP_PATH ) ) :
|
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 |
-
|
94 |
-
endif;
|
95 |
-
|
96 |
-
endif;
|
97 |
-
|
98 |
-
krsort( $files );
|
99 |
-
|
100 |
-
// Don't include the currently running backup
|
101 |
-
if ( $key = array_search( trailingslashit( hmbkp_path() ) . hmbkp_in_progress(), $files ) )
|
102 |
-
unset( $files[$key] );
|
103 |
-
|
104 |
-
return $files;
|
105 |
-
|
106 |
-
}
|
107 |
-
|
108 |
-
/**
|
109 |
-
* Delete a backup file
|
110 |
-
*
|
111 |
-
* @param $file base64 encoded filename
|
112 |
-
*/
|
113 |
-
function hmbkp_delete_backup( $file ) {
|
114 |
-
|
115 |
-
$file = base64_decode( $file );
|
116 |
-
|
117 |
-
// Delete the file
|
118 |
-
if ( ( strpos( $file, hmbkp_path() ) !== false || strpos( $file, WP_CONTENT_DIR . '/backups' ) !== false ) && file_exists( $file ) )
|
119 |
-
unlink( $file );
|
120 |
-
|
121 |
-
}
|
122 |
-
|
123 |
-
/**
|
124 |
-
* Email backup.
|
125 |
-
*
|
126 |
-
* @param $file
|
127 |
-
* @return bool
|
128 |
-
*/
|
129 |
-
function hmbkp_email_backup() {
|
130 |
-
|
131 |
-
$file = HM_Backup::get_instance()->archive_filepath();
|
132 |
-
|
133 |
-
if ( ! hmbkp_get_email_address() || ! file_exists( $file ) )
|
134 |
-
return;
|
135 |
-
|
136 |
-
update_option( 'hmbkp_email_error', 'hmbkp_email_failed' );
|
137 |
-
|
138 |
-
// Raise the memory and time limit
|
139 |
-
@ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
|
140 |
-
@set_time_limit( 0 );
|
141 |
-
|
142 |
-
// @todo admin_url?
|
143 |
-
$download = get_bloginfo( 'wpurl' ) . '/wp-admin/tools.php?page=' . HMBKP_PLUGIN_SLUG . '&hmbkp_download=' . base64_encode( $file );
|
144 |
-
|
145 |
-
$domain = parse_url( get_bloginfo( 'url' ), PHP_URL_HOST ) . parse_url( get_bloginfo( 'url' ), PHP_URL_PATH );
|
146 |
-
|
147 |
-
$subject = sprintf( __( 'Backup of %s', 'hmbkp' ), $domain );
|
148 |
-
$message = sprintf( __( 'BackUpWordPress has completed a backup of your site %1$s.\n\nThe backup file should be attached to this email.\n\nYou can also download the backup file by clicking the link below:\n\n%2$s\n\nKind Regards\n\n The Happy BackUpWordPress Backup Emailing Robot', 'hmbkp' ), get_bloginfo( 'url' ), $download );
|
149 |
-
$headers = 'From: BackUpWordPress <' . get_bloginfo( 'admin_email' ) . '>' . "\r\n";
|
150 |
-
|
151 |
-
// Try to send the email
|
152 |
-
$sent = wp_mail( array_filter( hmbkp_get_email_address(), 'is_email' ), $subject, $message, $headers, $file );
|
153 |
-
|
154 |
-
// If it failed- Try to send a download link - The file was probably too large.
|
155 |
-
if ( ! $sent ) :
|
156 |
-
|
157 |
-
$subject = sprintf( __( 'Backup of %s', 'hmbkp' ), $domain );
|
158 |
-
$message = sprintf( __( 'BackUpWordPress has completed a backup of your site %1$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%2$s\n\nKind Regards\n\n The Happy BackUpWordPress Backup Emailing Robot', 'hmbkp' ), get_bloginfo( 'url' ), $download );
|
159 |
-
|
160 |
-
$sent = wp_mail( array_filter( hmbkp_get_email_address(), 'is_email' ), $subject, $message, $headers );
|
161 |
-
|
162 |
-
endif;
|
163 |
-
|
164 |
-
// Set option for email not sent error
|
165 |
-
if ( $sent )
|
166 |
-
delete_option( 'hmbkp_email_error' );
|
167 |
-
|
168 |
-
return true;
|
169 |
-
|
170 |
-
}
|
171 |
-
|
172 |
-
/**
|
173 |
-
* Set the status of the running backup
|
174 |
-
*
|
175 |
-
* @param string $message. (default: '')
|
176 |
-
* @return void
|
177 |
-
*/
|
178 |
-
function hmbkp_set_status( $message = '' ) {
|
179 |
-
|
180 |
-
$file = hmbkp_path() . '/.backup_running';
|
181 |
-
|
182 |
-
if ( ! $handle = @fopen( $file, 'w' ) )
|
183 |
-
return;
|
184 |
-
|
185 |
-
fwrite( $handle, HM_Backup::get_instance()->archive_filename() . '::' . $message );
|
186 |
-
|
187 |
-
fclose( $handle );
|
188 |
-
|
189 |
-
}
|
190 |
-
|
191 |
-
/**
|
192 |
-
* Get the status of the running backup
|
193 |
-
*
|
194 |
-
* @return string
|
195 |
-
*/
|
196 |
-
function hmbkp_get_status() {
|
197 |
-
|
198 |
-
if ( ! file_exists( hmbkp_path() . '/.backup_running' ) )
|
199 |
-
return '';
|
200 |
-
|
201 |
-
return end( explode( '::', file_get_contents( hmbkp_path() . '/.backup_running' ) ) );
|
202 |
-
|
203 |
-
}
|
204 |
-
|
205 |
-
/**
|
206 |
-
* Get the list of excludes
|
207 |
-
*
|
208 |
-
* @return bool
|
209 |
-
*/
|
210 |
-
function hmbkp_get_excludes() {
|
211 |
-
|
212 |
-
if ( defined( 'HMBKP_EXCLUDE' ) && HMBKP_EXCLUDE )
|
213 |
-
return HMBKP_EXCLUDE;
|
214 |
-
|
215 |
-
if ( get_option( 'hmbkp_excludes' ) )
|
216 |
-
return get_option( 'hmbkp_excludes' );
|
217 |
-
|
218 |
-
return '';
|
219 |
-
|
220 |
-
}
|
221 |
-
|
222 |
-
/**
|
223 |
-
* Return an array of invalid custom exclude rules
|
224 |
-
*
|
225 |
-
* @return array
|
226 |
-
*/
|
227 |
-
function hmbkp_invalid_custom_excludes() {
|
228 |
-
|
229 |
-
$invalid_rules = array();
|
230 |
-
|
231 |
-
// Check if any absolute path excludes actually exist
|
232 |
-
if ( $excludes = hmbkp_get_excludes() )
|
233 |
-
|
234 |
-
foreach ( explode( ',', $excludes ) as $rule )
|
235 |
-
if ( ( $rule = trim( $rule ) ) && in_array( substr( $rule, 0, 1 ), array( '/', '\\' ) ) && ! file_exists( $rule ) && ! file_exists( hmbkp_get_home_path() . $rule ) && ! file_exists( trailingslashit( hmbkp_get_home_path() ) . $rule ) )
|
236 |
-
$invalid_rules[] = $rule;
|
237 |
-
|
238 |
-
return array_filter( $invalid_rules );
|
239 |
-
|
240 |
-
}
|
241 |
-
|
242 |
-
/**
|
243 |
-
* Return an array of valid custom exclude rules
|
244 |
-
*
|
245 |
-
* @return array
|
246 |
-
*/
|
247 |
-
function hmbkp_valid_custom_excludes() {
|
248 |
-
|
249 |
-
$valid_rules = array();
|
250 |
-
|
251 |
-
$excludes = hmbkp_get_excludes();
|
252 |
-
|
253 |
-
$valid_rules = array_diff( explode( ',', $excludes ), hmbkp_invalid_custom_excludes() );
|
254 |
-
|
255 |
-
return array_filter( array_map( 'trim', $valid_rules ) );
|
256 |
-
|
257 |
-
}
|
258 |
-
|
259 |
-
/**
|
260 |
-
* Check if a backup is running
|
261 |
-
*
|
262 |
-
* @return bool
|
263 |
-
*/
|
264 |
-
function hmbkp_in_progress() {
|
265 |
-
return file_exists( hmbkp_path() . '/.backup_running' ) ? reset( explode( '::', file_get_contents( hmbkp_path() .'/.backup_running' ) ) ) : '';
|
266 |
-
}
|
267 |
-
|
268 |
-
/**
|
269 |
-
* Get the exclude string from HM Backup
|
270 |
-
*
|
271 |
-
* @param string $context
|
272 |
-
* @return string
|
273 |
-
*/
|
274 |
-
function hmbkp_exclude_string( $context ) {
|
275 |
-
return HM_Backup::get_instance()->exclude_string( $context );
|
276 |
-
}
|
277 |
-
|
278 |
-
function hmbkp_backup_errors() {
|
279 |
-
|
280 |
-
if ( ! file_exists( hmbkp_path() . '/.backup_errors' ) )
|
281 |
-
return '';
|
282 |
-
|
283 |
-
return file_get_contents( hmbkp_path() . '/.backup_errors' );
|
284 |
-
|
285 |
-
}
|
286 |
-
|
287 |
-
function hmbkp_backup_warnings() {
|
288 |
-
|
289 |
-
if ( ! file_exists( hmbkp_path() . '/.backup_warnings' ) )
|
290 |
-
return '';
|
291 |
-
|
292 |
-
return file_get_contents( hmbkp_path() . '/.backup_warnings' );
|
293 |
-
|
294 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
functions/core.functions.php
DELETED
@@ -1,558 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Setup the plugin defaults on activation
|
5 |
-
*/
|
6 |
-
function hmbkp_activate() {
|
7 |
-
|
8 |
-
hmbkp_deactivate();
|
9 |
-
|
10 |
-
hmbkp_setup_schedule();
|
11 |
-
|
12 |
-
}
|
13 |
-
|
14 |
-
/**
|
15 |
-
* Cleanup on plugin deactivation
|
16 |
-
*
|
17 |
-
* Removes options and clears all cron schedules
|
18 |
-
*/
|
19 |
-
function hmbkp_deactivate() {
|
20 |
-
|
21 |
-
hmbkp_setup_hm_backup();
|
22 |
-
|
23 |
-
// Options to delete
|
24 |
-
$options = array(
|
25 |
-
'hmbkp_zip_path',
|
26 |
-
'hmbkp_mysqldump_path',
|
27 |
-
'hmbkp_path',
|
28 |
-
'hmbkp_running',
|
29 |
-
'hmbkp_status',
|
30 |
-
'hmbkp_complete',
|
31 |
-
'hmbkp_email_error'
|
32 |
-
);
|
33 |
-
|
34 |
-
foreach ( $options as $option )
|
35 |
-
delete_option( $option );
|
36 |
-
|
37 |
-
delete_transient( 'hmbkp_running' );
|
38 |
-
delete_transient( 'hmbkp_estimated_filesize' );
|
39 |
-
|
40 |
-
// Clear cron
|
41 |
-
wp_clear_scheduled_hook( 'hmbkp_schedule_backup_hook' );
|
42 |
-
wp_clear_scheduled_hook( 'hmbkp_schedule_single_backup_hook' );
|
43 |
-
|
44 |
-
hmbkp_cleanup();
|
45 |
-
|
46 |
-
}
|
47 |
-
|
48 |
-
/**
|
49 |
-
* Handles anything that needs to be
|
50 |
-
* done when the plugin is updated
|
51 |
-
*/
|
52 |
-
function hmbkp_update() {
|
53 |
-
|
54 |
-
// Every update
|
55 |
-
if ( version_compare( HMBKP_VERSION, get_option( 'hmbkp_plugin_version' ), '>' ) ) {
|
56 |
-
|
57 |
-
hmbkp_deactivate();
|
58 |
-
|
59 |
-
// Force .htaccess to be re-written
|
60 |
-
if ( file_exists( hmbkp_path() . '/.htaccess' ) )
|
61 |
-
unlink( hmbkp_path() . '/.htaccess' );
|
62 |
-
|
63 |
-
}
|
64 |
-
|
65 |
-
// Update from backUpWordPress 0.4.5
|
66 |
-
if ( get_option( 'bkpwp_max_backups' ) ) :
|
67 |
-
|
68 |
-
// Carry over the custom path
|
69 |
-
if ( $legacy_path = get_option( 'bkpwppath' ) )
|
70 |
-
update_option( 'hmbkp_path', $legacy_path );
|
71 |
-
|
72 |
-
// Options to remove
|
73 |
-
$legacy_options = array(
|
74 |
-
'bkpwp_archive_types',
|
75 |
-
'bkpwp_automail_from',
|
76 |
-
'bkpwp_domain',
|
77 |
-
'bkpwp_domain_path',
|
78 |
-
'bkpwp_easy_mode',
|
79 |
-
'bkpwp_excludelists',
|
80 |
-
'bkpwp_install_user',
|
81 |
-
'bkpwp_listmax_backups',
|
82 |
-
'bkpwp_max_backups',
|
83 |
-
'bkpwp_presets',
|
84 |
-
'bkpwp_reccurrences',
|
85 |
-
'bkpwp_schedules',
|
86 |
-
'bkpwp_calculation',
|
87 |
-
'bkpwppath',
|
88 |
-
'bkpwp_status_config',
|
89 |
-
'bkpwp_status'
|
90 |
-
);
|
91 |
-
|
92 |
-
foreach ( $legacy_options as $option )
|
93 |
-
delete_option( $option );
|
94 |
-
|
95 |
-
global $wp_roles;
|
96 |
-
|
97 |
-
$wp_roles->remove_cap( 'administrator','manage_backups' );
|
98 |
-
$wp_roles->remove_cap( 'administrator','download_backups' );
|
99 |
-
|
100 |
-
wp_clear_scheduled_hook( 'bkpwp_schedule_bkpwp_hook' );
|
101 |
-
|
102 |
-
endif;
|
103 |
-
|
104 |
-
// Update the stored version
|
105 |
-
if ( get_option( 'hmbkp_plugin_version' ) !== HMBKP_VERSION )
|
106 |
-
update_option( 'hmbkp_plugin_version', HMBKP_VERSION );
|
107 |
-
|
108 |
-
}
|
109 |
-
|
110 |
-
/**
|
111 |
-
* Take a file size and return a human readable
|
112 |
-
* version
|
113 |
-
*
|
114 |
-
* @param int $size
|
115 |
-
* @param string $unit. (default: null)
|
116 |
-
* @param string $retstring. (default: null)
|
117 |
-
* @param bool $si. (default: true)
|
118 |
-
* @return int
|
119 |
-
*/
|
120 |
-
function hmbkp_size_readable( $size, $unit = null, $retstring = '%01.2f %s', $si = true ) {
|
121 |
-
|
122 |
-
// Units
|
123 |
-
if ( $si === true ) :
|
124 |
-
$sizes = array( 'B', 'kB', 'MB', 'GB', 'TB', 'PB' );
|
125 |
-
$mod = 1000;
|
126 |
-
|
127 |
-
else :
|
128 |
-
$sizes = array('B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB');
|
129 |
-
$mod = 1024;
|
130 |
-
|
131 |
-
endif;
|
132 |
-
|
133 |
-
$ii = count( $sizes ) - 1;
|
134 |
-
|
135 |
-
// Max unit
|
136 |
-
$unit = array_search( (string) $unit, $sizes );
|
137 |
-
|
138 |
-
if ( is_null( $unit ) || $unit === false )
|
139 |
-
$unit = $ii;
|
140 |
-
|
141 |
-
// Loop
|
142 |
-
$i = 0;
|
143 |
-
|
144 |
-
while ( $unit != $i && $size >= 1024 && $i < $ii ) {
|
145 |
-
$size /= $mod;
|
146 |
-
$i++;
|
147 |
-
}
|
148 |
-
|
149 |
-
return sprintf( $retstring, $size, $sizes[$i] );
|
150 |
-
}
|
151 |
-
|
152 |
-
/**
|
153 |
-
* Add daily as a cron schedule choice
|
154 |
-
*
|
155 |
-
* @todo can we not use the built in schedules
|
156 |
-
* @param array $recc
|
157 |
-
* @return array $recc
|
158 |
-
*/
|
159 |
-
function hmbkp_more_reccurences( $recc ) {
|
160 |
-
|
161 |
-
$hmbkp_reccurrences = array(
|
162 |
-
'hmbkp_weekly' => array( 'interval' => 604800, 'display' => 'every week' ),
|
163 |
-
'hmbkp_fortnightly' => array( 'interval' => 1209600, 'display' => 'once a fortnight' ),
|
164 |
-
'hmbkp_monthly' => array( 'interval' => 2629743.83 , 'display' => 'once a month' )
|
165 |
-
);
|
166 |
-
|
167 |
-
return array_merge( $recc, $hmbkp_reccurrences );
|
168 |
-
}
|
169 |
-
add_filter( 'cron_schedules', 'hmbkp_more_reccurences' );
|
170 |
-
|
171 |
-
/**
|
172 |
-
* Recursively delete a directory including
|
173 |
-
* all the files and sub-directories.
|
174 |
-
*
|
175 |
-
* @param string $dir
|
176 |
-
*/
|
177 |
-
function hmbkp_rmdirtree( $dir ) {
|
178 |
-
|
179 |
-
if ( is_file( $dir ) )
|
180 |
-
unlink( $dir );
|
181 |
-
|
182 |
-
if ( ! is_dir( $dir ) )
|
183 |
-
return false;
|
184 |
-
|
185 |
-
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir ), RecursiveIteratorIterator::CHILD_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD );
|
186 |
-
|
187 |
-
foreach ( $files as $file ) {
|
188 |
-
|
189 |
-
if ( $file->isDir() )
|
190 |
-
@rmdir( $file->getPathname() );
|
191 |
-
|
192 |
-
else
|
193 |
-
@unlink( $file->getPathname() );
|
194 |
-
|
195 |
-
}
|
196 |
-
|
197 |
-
@rmdir( $dir );
|
198 |
-
|
199 |
-
}
|
200 |
-
|
201 |
-
/**
|
202 |
-
* Calculate the size of the backup
|
203 |
-
*
|
204 |
-
* Doesn't currently take into account for
|
205 |
-
* compression
|
206 |
-
*
|
207 |
-
* @return string
|
208 |
-
*/
|
209 |
-
function hmbkp_calculate() {
|
210 |
-
|
211 |
-
@ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
|
212 |
-
|
213 |
-
// Check cache
|
214 |
-
if ( $filesize = get_transient( 'hmbkp_estimated_filesize' ) )
|
215 |
-
return hmbkp_size_readable( $filesize, null, '%01u %s' );
|
216 |
-
|
217 |
-
$filesize = 0;
|
218 |
-
|
219 |
-
// Don't include database if files only
|
220 |
-
if ( ! hmbkp_get_files_only() ) {
|
221 |
-
|
222 |
-
global $wpdb;
|
223 |
-
|
224 |
-
$res = $wpdb->get_results( 'SHOW TABLE STATUS FROM ' . DB_NAME, ARRAY_A );
|
225 |
-
|
226 |
-
foreach ( $res as $r )
|
227 |
-
$filesize += (float) $r['Data_length'];
|
228 |
-
|
229 |
-
}
|
230 |
-
|
231 |
-
if ( ! hmbkp_get_database_only() ) {
|
232 |
-
|
233 |
-
// Get rid of any cached filesizes
|
234 |
-
clearstatcache();
|
235 |
-
|
236 |
-
foreach ( HM_Backup::get_instance()->files() as $file )
|
237 |
-
$filesize += (float) @filesize( hmbkp_get_home_path() . $file );
|
238 |
-
|
239 |
-
}
|
240 |
-
|
241 |
-
// Cache in a transient for a week
|
242 |
-
set_transient( 'hmbkp_estimated_filesize', $filesize, 604800 );
|
243 |
-
|
244 |
-
return hmbkp_size_readable( $filesize, null, '%01u %s' );
|
245 |
-
|
246 |
-
}
|
247 |
-
|
248 |
-
/**
|
249 |
-
* Calculate the total filesize of all backups
|
250 |
-
*
|
251 |
-
* @return string
|
252 |
-
*/
|
253 |
-
function hmbkp_total_filesize() {
|
254 |
-
|
255 |
-
$files = hmbkp_get_backups();
|
256 |
-
$filesize = 0;
|
257 |
-
|
258 |
-
clearstatcache();
|
259 |
-
|
260 |
-
foreach ( $files as $f )
|
261 |
-
$filesize += @filesize( $f );
|
262 |
-
|
263 |
-
return hmbkp_size_readable( $filesize );
|
264 |
-
|
265 |
-
}
|
266 |
-
|
267 |
-
|
268 |
-
/**
|
269 |
-
* Set Up the shedule.
|
270 |
-
* This should runn according to the Frequency defined, or set in the option.
|
271 |
-
*
|
272 |
-
* @access public
|
273 |
-
* @return void
|
274 |
-
*/
|
275 |
-
function hmbkp_setup_schedule() {
|
276 |
-
|
277 |
-
// Clear any old schedules
|
278 |
-
wp_clear_scheduled_hook( 'hmbkp_schedule_backup_hook' );
|
279 |
-
|
280 |
-
if( hmbkp_get_disable_automatic_backup() )
|
281 |
-
return;
|
282 |
-
|
283 |
-
// Default to 11 in the evening
|
284 |
-
$time = '23:00';
|
285 |
-
|
286 |
-
// Allow it to be overridden
|
287 |
-
if ( defined( 'HMBKP_DAILY_SCHEDULE_TIME' ) && HMBKP_DAILY_SCHEDULE_TIME )
|
288 |
-
$time = HMBKP_DAILY_SCHEDULE_TIME;
|
289 |
-
|
290 |
-
$offset = current_time( 'timestamp' ) - time();
|
291 |
-
$scheduletime_UTC = strtotime( $time ) - $offset;
|
292 |
-
|
293 |
-
if( defined( 'HMBKP_SCHEDULE_FREQUENCY' ) && HMBKP_SCHEDULE_FREQUENCY )
|
294 |
-
$schedule_frequency = HMBKP_SCHEDULE_FREQUENCY;
|
295 |
-
elseif( get_option('hmbkp_schedule_frequency') )
|
296 |
-
$schedule_frequency = get_option('hmbkp_schedule_frequency');
|
297 |
-
else
|
298 |
-
$schedule_frequency = 'daily';
|
299 |
-
|
300 |
-
// Advance by the interval. (except daily, when it will only happen if shcheduled time is in the past. )
|
301 |
-
if( $schedule_frequency != 'daily' || $schedule_frequency == 'daily' && $scheduletime_UTC < time() ) {
|
302 |
-
$interval = wp_get_schedules('hmbkp_schedule_backup_hook');
|
303 |
-
$interval = $interval[ $schedule_frequency ]['interval'];
|
304 |
-
$scheduletime_UTC = $scheduletime_UTC + $interval;
|
305 |
-
}
|
306 |
-
|
307 |
-
wp_schedule_event( $scheduletime_UTC, $schedule_frequency, 'hmbkp_schedule_backup_hook' );
|
308 |
-
}
|
309 |
-
|
310 |
-
|
311 |
-
/**
|
312 |
-
* Get the absolute filesystem path to the root of the WordPress installation
|
313 |
-
* A clone of the get_home_path function found in wp-admin
|
314 |
-
*
|
315 |
-
* @uses get_option
|
316 |
-
* @return string Full filesystem path to the root of the WordPress installation
|
317 |
-
*/
|
318 |
-
function hmbkp_get_home_path() {
|
319 |
-
$home = get_option( 'home' );
|
320 |
-
$siteurl = get_option( 'siteurl' );
|
321 |
-
if ( $home != '' && $home != $siteurl ) {
|
322 |
-
$wp_path_rel_to_home = str_replace( $home, '', $siteurl ); /* $siteurl - $home */
|
323 |
-
$pos = strrpos( $_SERVER["SCRIPT_FILENAME"], $wp_path_rel_to_home );
|
324 |
-
$home_path = substr( $_SERVER["SCRIPT_FILENAME"], 0, $pos );
|
325 |
-
$home_path = trailingslashit( $home_path );
|
326 |
-
} else {
|
327 |
-
$home_path = ABSPATH;
|
328 |
-
}
|
329 |
-
|
330 |
-
return $home_path;
|
331 |
-
}
|
332 |
-
|
333 |
-
|
334 |
-
/**
|
335 |
-
* Get the path to the backups directory
|
336 |
-
*
|
337 |
-
* Will try to create it if it doesn't exist
|
338 |
-
* and will fallback to default if a custom dir
|
339 |
-
* isn't writable.
|
340 |
-
*/
|
341 |
-
function hmbkp_path() {
|
342 |
-
|
343 |
-
$path = get_option( 'hmbkp_path' );
|
344 |
-
|
345 |
-
// Allow the backups path to be defined
|
346 |
-
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH )
|
347 |
-
$path = HMBKP_PATH;
|
348 |
-
|
349 |
-
// If the dir doesn't exist or isn't writable then use wp-content/backups instead
|
350 |
-
if ( ( ! $path || ! is_writable( $path ) ) && hmbkp_conform_dir( $path ) != hmbkp_path_default() )
|
351 |
-
$path = hmbkp_path_default();
|
352 |
-
|
353 |
-
// Create the backups directory if it doesn't exist
|
354 |
-
if ( is_writable( dirname( $path ) ) && ! is_dir( $path ) )
|
355 |
-
mkdir( $path, 0755 );
|
356 |
-
|
357 |
-
if ( get_option( 'hmbkp_path' ) != $path )
|
358 |
-
update_option( 'hmbkp_path', $path );
|
359 |
-
|
360 |
-
// Secure the directory with a .htaccess file
|
361 |
-
$htaccess = $path . '/.htaccess';
|
362 |
-
|
363 |
-
$contents[] = '# ' . sprintf( __( 'This %s file ensures that other people cannot download your backup files.', 'hmbkp' ), '.htaccess' );
|
364 |
-
$contents[] = '';
|
365 |
-
$contents[] = '<IfModule mod_rewrite.c>';
|
366 |
-
$contents[] = 'RewriteEngine On';
|
367 |
-
$contents[] = 'RewriteCond %{QUERY_STRING} !key=' . md5( HMBKP_SECURE_KEY );
|
368 |
-
$contents[] = 'RewriteRule (.*) - [F]';
|
369 |
-
$contents[] = '</IfModule>';
|
370 |
-
$contents[] = '';
|
371 |
-
|
372 |
-
if ( ! file_exists( $htaccess ) && is_writable( $path ) && require_once( ABSPATH . '/wp-admin/includes/misc.php' ) )
|
373 |
-
insert_with_markers( $htaccess, 'BackUpWordPress', $contents );
|
374 |
-
|
375 |
-
return hmbkp_conform_dir( $path );
|
376 |
-
}
|
377 |
-
|
378 |
-
/**
|
379 |
-
* Return the default backup path
|
380 |
-
*
|
381 |
-
* @return string path
|
382 |
-
*/
|
383 |
-
function hmbkp_path_default() {
|
384 |
-
return hmbkp_conform_dir( WP_CONTENT_DIR . '/backups' );
|
385 |
-
}
|
386 |
-
|
387 |
-
/**
|
388 |
-
* Move the backup directory and all existing backup files to a new
|
389 |
-
* location
|
390 |
-
*
|
391 |
-
* @param string $from path to move the backups dir from
|
392 |
-
* @param string $to path to move the backups dir to
|
393 |
-
* @return void
|
394 |
-
*/
|
395 |
-
function hmbkp_path_move( $from, $to ) {
|
396 |
-
|
397 |
-
// Create the custom backups directory if it doesn't exist
|
398 |
-
if ( is_writable( dirname( $to ) ) && ! is_dir( $to ) )
|
399 |
-
mkdir( $to, 0755 );
|
400 |
-
|
401 |
-
if ( ! is_dir( $to ) || ! is_writable( $to ) || ! is_dir( $from ) )
|
402 |
-
return false;
|
403 |
-
|
404 |
-
hmbkp_cleanup();
|
405 |
-
|
406 |
-
if ( $handle = opendir( $from ) ) :
|
407 |
-
|
408 |
-
while ( false !== ( $file = readdir( $handle ) ) )
|
409 |
-
if ( $file != '.' && $file != '..' )
|
410 |
-
rename( trailingslashit( $from ) . $file, trailingslashit( $to ) . $file );
|
411 |
-
|
412 |
-
closedir( $handle );
|
413 |
-
|
414 |
-
endif;
|
415 |
-
|
416 |
-
hmbkp_rmdirtree( $from );
|
417 |
-
|
418 |
-
}
|
419 |
-
|
420 |
-
/**
|
421 |
-
* The maximum number of backups to keep
|
422 |
-
* defaults to 10
|
423 |
-
*
|
424 |
-
* @return int
|
425 |
-
*/
|
426 |
-
function hmbkp_max_backups() {
|
427 |
-
|
428 |
-
if ( defined( 'HMBKP_MAX_BACKUPS' ) && is_numeric( HMBKP_MAX_BACKUPS ) )
|
429 |
-
return (int) HMBKP_MAX_BACKUPS;
|
430 |
-
|
431 |
-
if ( get_option( 'hmbkp_max_backups' ) )
|
432 |
-
return (int) get_option( 'hmbkp_max_backups', 10 );
|
433 |
-
|
434 |
-
return 10;
|
435 |
-
|
436 |
-
}
|
437 |
-
|
438 |
-
/**
|
439 |
-
* Whether to only backup files
|
440 |
-
*
|
441 |
-
* @return bool
|
442 |
-
*/
|
443 |
-
function hmbkp_get_files_only() {
|
444 |
-
|
445 |
-
if ( defined( 'HMBKP_FILES_ONLY' ) && HMBKP_FILES_ONLY )
|
446 |
-
return true;
|
447 |
-
|
448 |
-
if ( get_option( 'hmbkp_files_only' ) )
|
449 |
-
return true;
|
450 |
-
|
451 |
-
return false;
|
452 |
-
}
|
453 |
-
|
454 |
-
/**
|
455 |
-
* Whether to only backup the database
|
456 |
-
*
|
457 |
-
* @return bool
|
458 |
-
*/
|
459 |
-
function hmbkp_get_database_only() {
|
460 |
-
|
461 |
-
if ( defined( 'HMBKP_DATABASE_ONLY' ) && HMBKP_DATABASE_ONLY )
|
462 |
-
return true;
|
463 |
-
|
464 |
-
if ( get_option( 'hmbkp_database_only' ) )
|
465 |
-
return true;
|
466 |
-
|
467 |
-
return false;
|
468 |
-
|
469 |
-
}
|
470 |
-
|
471 |
-
/**
|
472 |
-
* Returns defined email address or email address saved in options.
|
473 |
-
* If none set, return empty string.
|
474 |
-
*/
|
475 |
-
function hmbkp_get_email_address( $type = 'array' ) {
|
476 |
-
|
477 |
-
$email = '';
|
478 |
-
|
479 |
-
if ( defined( 'HMBKP_EMAIL' ) && HMBKP_EMAIL )
|
480 |
-
$email = HMBKP_EMAIL;
|
481 |
-
|
482 |
-
elseif ( get_option( 'hmbkp_email_address' ) )
|
483 |
-
$email = get_option( 'hmbkp_email_address' );
|
484 |
-
|
485 |
-
if ( ! empty( $email ) && $type == 'array' )
|
486 |
-
$email = array_filter( array_map( 'trim', explode( ',', $email ) ) );
|
487 |
-
|
488 |
-
return $email;
|
489 |
-
|
490 |
-
}
|
491 |
-
|
492 |
-
/**
|
493 |
-
* Are automatic backups disabled
|
494 |
-
*
|
495 |
-
* @return bool
|
496 |
-
*/
|
497 |
-
function hmbkp_get_disable_automatic_backup() {
|
498 |
-
|
499 |
-
if ( defined( 'HMBKP_DISABLE_AUTOMATIC_BACKUP' ) && HMBKP_DISABLE_AUTOMATIC_BACKUP )
|
500 |
-
return true;
|
501 |
-
|
502 |
-
if ( get_option( 'hmbkp_disable_automatic_backup' ) )
|
503 |
-
return true;
|
504 |
-
|
505 |
-
return false;
|
506 |
-
|
507 |
-
}
|
508 |
-
|
509 |
-
/**
|
510 |
-
* Check if a backup is possible with regards to file
|
511 |
-
* permissions etc.
|
512 |
-
*
|
513 |
-
* @return bool
|
514 |
-
*/
|
515 |
-
function hmbkp_possible() {
|
516 |
-
|
517 |
-
if ( ! is_writable( hmbkp_path() ) || ! is_dir( hmbkp_path() ) || hmbkp_is_safe_mode_active() )
|
518 |
-
return false;
|
519 |
-
|
520 |
-
if ( defined( 'HMBKP_FILES_ONLY' ) && HMBKP_FILES_ONLY && defined( 'HMBKP_DATABASE_ONLY' ) && HMBKP_DATABASE_ONLY )
|
521 |
-
return false;
|
522 |
-
|
523 |
-
return true;
|
524 |
-
}
|
525 |
-
|
526 |
-
/**
|
527 |
-
* Remove any non backup.zip files from the backups dir.
|
528 |
-
*
|
529 |
-
* @return void
|
530 |
-
*/
|
531 |
-
function hmbkp_cleanup() {
|
532 |
-
|
533 |
-
delete_option( 'hmbkp_email_error' );
|
534 |
-
|
535 |
-
$hmbkp_path = hmbkp_path();
|
536 |
-
|
537 |
-
if ( ! is_dir( $hmbkp_path ) )
|
538 |
-
return;
|
539 |
-
|
540 |
-
if ( $handle = opendir( $hmbkp_path ) ) :
|
541 |
-
|
542 |
-
while ( false !== ( $file = readdir( $handle ) ) )
|
543 |
-
if ( ! in_array( $file, array( '.', '..', '.htaccess' ) ) && pathinfo( $file, PATHINFO_EXTENSION ) !== 'zip' )
|
544 |
-
hmbkp_rmdirtree( trailingslashit( $hmbkp_path ) . $file );
|
545 |
-
|
546 |
-
closedir( $handle );
|
547 |
-
|
548 |
-
endif;
|
549 |
-
|
550 |
-
}
|
551 |
-
|
552 |
-
function hmbkp_conform_dir( $dir ) {
|
553 |
-
return HM_Backup::get_instance()->conform_dir( $dir );
|
554 |
-
}
|
555 |
-
|
556 |
-
function hmbkp_is_safe_mode_active() {
|
557 |
-
return HM_Backup::get_instance()->is_safe_mode_active();
|
558 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
functions/core.php
ADDED
@@ -0,0 +1,362 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Setup the plugin defaults on activation
|
5 |
+
*/
|
6 |
+
function hmbkp_activate() {
|
7 |
+
|
8 |
+
hmbkp_deactivate();
|
9 |
+
|
10 |
+
}
|
11 |
+
|
12 |
+
/**
|
13 |
+
* Cleanup on plugin deactivation
|
14 |
+
*
|
15 |
+
* Removes options and clears all cron schedules
|
16 |
+
*/
|
17 |
+
function hmbkp_deactivate() {
|
18 |
+
|
19 |
+
// Options to delete
|
20 |
+
$options = array(
|
21 |
+
'hmbkp_zip_path',
|
22 |
+
'hmbkp_mysqldump_path',
|
23 |
+
'hmbkp_path',
|
24 |
+
'hmbkp_running',
|
25 |
+
'hmbkp_status',
|
26 |
+
'hmbkp_complete',
|
27 |
+
'hmbkp_email_error'
|
28 |
+
);
|
29 |
+
|
30 |
+
foreach ( $options as $option )
|
31 |
+
delete_option( $option );
|
32 |
+
|
33 |
+
delete_transient( 'hmbkp_running' );
|
34 |
+
delete_transient( 'hmbkp_estimated_filesize' );
|
35 |
+
|
36 |
+
// Clear cron
|
37 |
+
wp_clear_scheduled_hook( 'hmbkp_schedule_backup_hook' );
|
38 |
+
wp_clear_scheduled_hook( 'hmbkp_schedule_single_backup_hook' );
|
39 |
+
|
40 |
+
hmbkp_cleanup();
|
41 |
+
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Handles anything that needs to be
|
46 |
+
* done when the plugin is updated
|
47 |
+
*/
|
48 |
+
function hmbkp_update() {
|
49 |
+
|
50 |
+
// Update from backUpWordPress 0.4.5
|
51 |
+
if ( get_option( 'bkpwp_max_backups' ) ) {
|
52 |
+
|
53 |
+
// Carry over the custom path
|
54 |
+
if ( $legacy_path = get_option( 'bkpwppath' ) )
|
55 |
+
update_option( 'hmbkp_path', $legacy_path );
|
56 |
+
|
57 |
+
// Options to remove
|
58 |
+
$legacy_options = array(
|
59 |
+
'bkpwp_archive_types',
|
60 |
+
'bkpwp_automail_from',
|
61 |
+
'bkpwp_domain',
|
62 |
+
'bkpwp_domain_path',
|
63 |
+
'bkpwp_easy_mode',
|
64 |
+
'bkpwp_excludelists',
|
65 |
+
'bkpwp_install_user',
|
66 |
+
'bkpwp_listmax_backups',
|
67 |
+
'bkpwp_max_backups',
|
68 |
+
'bkpwp_presets',
|
69 |
+
'bkpwp_reccurrences',
|
70 |
+
'bkpwp_schedules',
|
71 |
+
'bkpwp_calculation',
|
72 |
+
'bkpwppath',
|
73 |
+
'bkpwp_status_config',
|
74 |
+
'bkpwp_status'
|
75 |
+
);
|
76 |
+
|
77 |
+
foreach ( $legacy_options as $option )
|
78 |
+
delete_option( $option );
|
79 |
+
|
80 |
+
global $wp_roles;
|
81 |
+
|
82 |
+
$wp_roles->remove_cap( 'administrator','manage_backups' );
|
83 |
+
$wp_roles->remove_cap( 'administrator','download_backups' );
|
84 |
+
|
85 |
+
wp_clear_scheduled_hook( 'bkpwp_schedule_bkpwp_hook' );
|
86 |
+
|
87 |
+
}
|
88 |
+
|
89 |
+
// Version 1 to 2
|
90 |
+
if ( version_compare ( '2.0' , get_option( 'hmbkp_plugin_version' ) ) ) {
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Setup a backwards compatible schedule
|
94 |
+
*/
|
95 |
+
$legacy_schedule = new HMBKP_Scheduled_Backup( 'backup' );
|
96 |
+
|
97 |
+
// Backup type
|
98 |
+
if ( ( defined( 'HMBKP_FILES_ONLY' ) && HMBKP_FILES_ONLY ) || get_option( 'hmbkp_files_only' ) )
|
99 |
+
$legacy_schedule->set_type( 'file' );
|
100 |
+
|
101 |
+
elseif ( ( defined( 'HMBKP_DATABASE_ONLY' ) && HMBKP_DATABASE_ONLY ) || get_option( 'hmbkp_database_only' ) )
|
102 |
+
$legacy_schedule->set_type( 'database' );
|
103 |
+
|
104 |
+
else
|
105 |
+
$legacy_schedule->set_type( 'complete' );
|
106 |
+
|
107 |
+
// Daily schedule time
|
108 |
+
if ( defined( 'HMBKP_DAILY_SCHEDULE_TIME' ) && HMBKP_DAILY_SCHEDULE_TIME )
|
109 |
+
$legacy_schedule->set_schedule_start_time( strtotime( HMBKP_DAILY_SCHEDULE_TIME ) );
|
110 |
+
|
111 |
+
// Backup schedule
|
112 |
+
$legacy_schedule->set_reoccurrence( str_replace( 'hmbkp_', '', get_option( 'hmbkp_schedule_frequency', 'daily' ) ) );
|
113 |
+
|
114 |
+
// Automatic backups disabled?
|
115 |
+
if ( ( defined( 'HMBKP_DISABLE_AUTOMATIC_BACKUP' ) && HMBKP_DISABLE_AUTOMATIC_BACKUP ) || get_option( 'hmbkp_disable_automatic_backup' ) )
|
116 |
+
$legacy_schedule->set_reoccurrence( 'manually' );
|
117 |
+
|
118 |
+
// Max backups
|
119 |
+
if ( defined( 'HMBKP_MAX_BACKUPS' ) && is_numeric( HMBKP_MAX_BACKUPS ) )
|
120 |
+
$legacy_schedule->set_max_backups( (int) HMBKP_MAX_BACKUPS );
|
121 |
+
|
122 |
+
else
|
123 |
+
$legacy_schedule->set_max_backups( (int) get_option( 'hmbkp_max_backups', 10 ) );
|
124 |
+
|
125 |
+
// Excludes
|
126 |
+
if ( get_option( 'hmbkp_excludes' ) )
|
127 |
+
$legacy_schedule->set_excludes( get_option( 'hmbkp_excludes' ) );
|
128 |
+
|
129 |
+
// Backup email
|
130 |
+
if ( defined( 'HMBKP_EMAIL' ) && is_email( HMBKP_EMAIL ) )
|
131 |
+
$legacy_schedule->set_service_options( 'HMBKP_Email_Service', array( 'email' => HMBKP_EMAIL ) );
|
132 |
+
|
133 |
+
elseif ( is_email( get_option( 'hmbkp_email_address' ) ) )
|
134 |
+
$legacy_schedule->set_service_options( 'HMBKP_Email_Service', array( 'email' => get_option( 'hmbkp_email_address' ) ) );
|
135 |
+
|
136 |
+
// Set the archive filename to what it used to be
|
137 |
+
$legacy_schedule->set_archive_filename( implode( '-', array( get_bloginfo( 'name' ), 'backup', date( 'Y-m-d-H-i-s', current_time( 'timestamp' ) ) ) ) . '.zip' );
|
138 |
+
|
139 |
+
$legacy_schedule->save();
|
140 |
+
|
141 |
+
// Remove the legacy options
|
142 |
+
foreach ( array( 'hmbkp_email', 'hmbkp_database_only', 'hmbkp_files_only', 'hmbkp_max_backups', 'hmbkp_email_address', 'hmbkp_email', 'hmbkp_schedule_frequency', 'hmbkp_disable_automatic_backup' ) as $option_name )
|
143 |
+
delete_option( $option_name );
|
144 |
+
|
145 |
+
|
146 |
+
}
|
147 |
+
|
148 |
+
// Every update
|
149 |
+
if ( version_compare( HMBKP_VERSION, get_option( 'hmbkp_plugin_version' ), '>' ) ) {
|
150 |
+
|
151 |
+
hmbkp_deactivate();
|
152 |
+
|
153 |
+
// Force .htaccess to be re-written
|
154 |
+
if ( file_exists( hmbkp_path() . '/.htaccess' ) )
|
155 |
+
unlink( hmbkp_path() . '/.htaccess' );
|
156 |
+
|
157 |
+
}
|
158 |
+
|
159 |
+
// Update the stored version
|
160 |
+
if ( get_option( 'hmbkp_plugin_version' ) !== HMBKP_VERSION )
|
161 |
+
update_option( 'hmbkp_plugin_version', HMBKP_VERSION );
|
162 |
+
|
163 |
+
}
|
164 |
+
|
165 |
+
/**
|
166 |
+
* Setup the default backup schedules
|
167 |
+
*/
|
168 |
+
function hmbkp_setup_default_schedules() {
|
169 |
+
|
170 |
+
$schedules = new HMBKP_Schedules;
|
171 |
+
|
172 |
+
if ( $schedules->get_schedules() )
|
173 |
+
return;
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Schedule a database backup daily and store backups
|
177 |
+
* for the last 2 weeks
|
178 |
+
*/
|
179 |
+
$database_daily = new HMBKP_Scheduled_Backup( 'default-1' );
|
180 |
+
$database_daily->set_type( 'database' );
|
181 |
+
$database_daily->set_reoccurrence( 'daily' );
|
182 |
+
$database_daily->set_max_backups( 14 );
|
183 |
+
$database_daily->save();
|
184 |
+
|
185 |
+
/**
|
186 |
+
* Schedule a complete backup to run weekly and store backups for
|
187 |
+
* the last 3 months
|
188 |
+
*/
|
189 |
+
$complete_weekly = new HMBKP_Scheduled_Backup( 'default-2' );
|
190 |
+
$complete_weekly->set_type( 'complete' );
|
191 |
+
$complete_weekly->set_reoccurrence( 'weekly' );
|
192 |
+
$complete_weekly->set_max_backups( 12 );
|
193 |
+
$complete_weekly->save();
|
194 |
+
|
195 |
+
function hmbkp_default_schedules_setup_warning() {
|
196 |
+
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has setup your default schedules.', 'hmbkp' ) . '</strong> ' . __( 'By default BackUpWordPress performs a daily backup of your database and a weekly backup of your database & files. You can modify these schedules.', 'hmbkp' ) . '</p></div>';
|
197 |
+
}
|
198 |
+
add_action( 'admin_notices', 'hmbkp_default_schedules_setup_warning' );
|
199 |
+
|
200 |
+
}
|
201 |
+
|
202 |
+
/**
|
203 |
+
* Add weekly, fortnightly and monthly as a cron schedule choices
|
204 |
+
*
|
205 |
+
* @param array $reccurrences
|
206 |
+
* @return array $reccurrences
|
207 |
+
*/
|
208 |
+
function hmbkp_more_reccurences( $reccurrences ) {
|
209 |
+
|
210 |
+
return array_merge( $reccurrences, array(
|
211 |
+
'weekly' => array( 'interval' => 604800, 'display' => 'Once Weekly' ),
|
212 |
+
'fortnightly' => array( 'interval' => 1209600, 'display' => 'Once Fortnightly' ),
|
213 |
+
'monthly' => array( 'interval' => 2629743.83 , 'display' => 'Once Monthly' )
|
214 |
+
) );
|
215 |
+
}
|
216 |
+
add_filter( 'cron_schedules', 'hmbkp_more_reccurences' );
|
217 |
+
|
218 |
+
/**
|
219 |
+
* Recursively delete a directory including
|
220 |
+
* all the files and sub-directories.
|
221 |
+
*
|
222 |
+
* @param string $dir
|
223 |
+
*/
|
224 |
+
function hmbkp_rmdirtree( $dir ) {
|
225 |
+
|
226 |
+
if ( is_file( $dir ) )
|
227 |
+
@unlink( $dir );
|
228 |
+
|
229 |
+
if ( ! is_dir( $dir ) )
|
230 |
+
return false;
|
231 |
+
|
232 |
+
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dir ), RecursiveIteratorIterator::CHILD_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD );
|
233 |
+
|
234 |
+
foreach ( $files as $file ) {
|
235 |
+
|
236 |
+
if ( $file->isDir() )
|
237 |
+
@rmdir( $file->getPathname() );
|
238 |
+
|
239 |
+
else
|
240 |
+
@unlink( $file->getPathname() );
|
241 |
+
|
242 |
+
}
|
243 |
+
|
244 |
+
@rmdir( $dir );
|
245 |
+
|
246 |
+
}
|
247 |
+
|
248 |
+
/**
|
249 |
+
* Get the path to the backups directory
|
250 |
+
*
|
251 |
+
* Will try to create it if it doesn't exist
|
252 |
+
* and will fallback to default if a custom dir
|
253 |
+
* isn't writable.
|
254 |
+
*/
|
255 |
+
function hmbkp_path() {
|
256 |
+
|
257 |
+
$path = get_option( 'hmbkp_path' );
|
258 |
+
|
259 |
+
// Allow the backups path to be defined
|
260 |
+
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH )
|
261 |
+
$path = HMBKP_PATH;
|
262 |
+
|
263 |
+
// If the dir doesn't exist or isn't writable then use wp-content/backups instead
|
264 |
+
if ( ( ! $path || ! is_writable( $path ) ) && HM_Backup::conform_dir( $path ) !== hmbkp_path_default() )
|
265 |
+
$path = hmbkp_path_default();
|
266 |
+
|
267 |
+
// Create the backups directory if it doesn't exist
|
268 |
+
if ( is_writable( dirname( $path ) ) && ! is_dir( $path ) )
|
269 |
+
mkdir( $path, 0755 );
|
270 |
+
|
271 |
+
if ( get_option( 'hmbkp_path' ) !== $path )
|
272 |
+
update_option( 'hmbkp_path', $path );
|
273 |
+
|
274 |
+
// Protect against directory browsing by including a index.html file
|
275 |
+
$index = $path . '/index.html';
|
276 |
+
|
277 |
+
if ( ! file_exists( $index ) && is_writable( $path ) )
|
278 |
+
file_put_contents( $index, '' );
|
279 |
+
|
280 |
+
return HM_Backup::conform_dir( $path );
|
281 |
+
|
282 |
+
}
|
283 |
+
|
284 |
+
/**
|
285 |
+
* Return the default backup path
|
286 |
+
*
|
287 |
+
* @return string path
|
288 |
+
*/
|
289 |
+
function hmbkp_path_default() {
|
290 |
+
return HM_Backup::conform_dir( WP_CONTENT_DIR . '/backups' );
|
291 |
+
}
|
292 |
+
|
293 |
+
/**
|
294 |
+
* Move the backup directory and all existing backup files to a new
|
295 |
+
* location
|
296 |
+
*
|
297 |
+
* @param string $from path to move the backups dir from
|
298 |
+
* @param string $to path to move the backups dir to
|
299 |
+
* @return void
|
300 |
+
*/
|
301 |
+
function hmbkp_path_move( $from, $to ) {
|
302 |
+
|
303 |
+
// Create the custom backups directory if it doesn't exist
|
304 |
+
if ( is_writable( dirname( $to ) ) && ! is_dir( $to ) )
|
305 |
+
mkdir( $to, 0755 );
|
306 |
+
|
307 |
+
if ( ! is_dir( $to ) || ! is_writable( $to ) || ! is_dir( $from ) )
|
308 |
+
return false;
|
309 |
+
|
310 |
+
hmbkp_cleanup();
|
311 |
+
|
312 |
+
if ( $handle = opendir( $from ) ) :
|
313 |
+
|
314 |
+
while ( false !== ( $file = readdir( $handle ) ) )
|
315 |
+
if ( $file !== '.' && $file !== '..' )
|
316 |
+
rename( trailingslashit( $from ) . $file, trailingslashit( $to ) . $file );
|
317 |
+
|
318 |
+
closedir( $handle );
|
319 |
+
|
320 |
+
endif;
|
321 |
+
|
322 |
+
hmbkp_rmdirtree( $from );
|
323 |
+
|
324 |
+
}
|
325 |
+
|
326 |
+
/**
|
327 |
+
* Check if a backup is possible with regards to file
|
328 |
+
* permissions etc.
|
329 |
+
*
|
330 |
+
* @return bool
|
331 |
+
*/
|
332 |
+
function hmbkp_possible() {
|
333 |
+
|
334 |
+
if ( ! is_writable( hmbkp_path() ) || ! is_dir( hmbkp_path() ) || HM_Backup::is_safe_mode_active() )
|
335 |
+
return false;
|
336 |
+
|
337 |
+
return true;
|
338 |
+
}
|
339 |
+
|
340 |
+
/**
|
341 |
+
* Remove any non backup.zip files from the backups dir.
|
342 |
+
*
|
343 |
+
* @return void
|
344 |
+
*/
|
345 |
+
function hmbkp_cleanup() {
|
346 |
+
|
347 |
+
$hmbkp_path = hmbkp_path();
|
348 |
+
|
349 |
+
if ( ! is_dir( $hmbkp_path ) )
|
350 |
+
return;
|
351 |
+
|
352 |
+
if ( $handle = opendir( $hmbkp_path ) ) :
|
353 |
+
|
354 |
+
while ( false !== ( $file = readdir( $handle ) ) )
|
355 |
+
if ( ! in_array( $file, array( '.', '..', 'index.html' ) ) && pathinfo( $file, PATHINFO_EXTENSION ) !== 'zip' )
|
356 |
+
hmbkp_rmdirtree( trailingslashit( $hmbkp_path ) . $file );
|
357 |
+
|
358 |
+
closedir( $handle );
|
359 |
+
|
360 |
+
endif;
|
361 |
+
|
362 |
+
}
|
functions/interface.functions.php
DELETED
@@ -1,202 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Displays a row in the manage backups table
|
5 |
-
*
|
6 |
-
* @param string $file
|
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>
|
20 |
-
<?php echo hmbkp_size_readable( filesize( $file ) ); ?>
|
21 |
-
</td>
|
22 |
-
|
23 |
-
<td>
|
24 |
-
|
25 |
-
<a href="tools.php?page=<?php echo HMBKP_PLUGIN_SLUG; ?>&hmbkp_download=<?php echo $encode; ?>"><?php _e( 'Download', 'hmbkp' ); ?></a> |
|
26 |
-
<a href="tools.php?page=<?php echo HMBKP_PLUGIN_SLUG; ?>&hmbkp_delete=<?php echo $encode ?>" class="delete"><?php _e( 'Delete', 'hmbkp' ); ?></a>
|
27 |
-
|
28 |
-
</td>
|
29 |
-
|
30 |
-
</tr>
|
31 |
-
|
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 |
-
<div id="setting-error-settings_updated" class="updated settings-error"><p><strong><?php _e( 'Settings saved.', 'hmbkp' ); ?></strong></p></div>
|
49 |
-
|
50 |
-
<?php 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 |
-
|
64 |
-
function hmbkp_path_exists_warning() {
|
65 |
-
$php_user = exec( 'whoami' );
|
66 |
-
$php_group = reset( explode( ' ', exec( 'groups' ) ) );
|
67 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress is almost ready.', 'hmbkp' ) . '</strong> ' . sprintf( __( 'The backups directory can\'t be created because your %1$s directory isn\'t writable, run %2$s or %3$s or create the folder yourself.', 'hmbkp' ), '<code>wp-content</code>', '<code>chown ' . $php_user . ':' . $php_group . ' ' . WP_CONTENT_DIR . '</code>', '<code>chmod 777 ' . WP_CONTENT_DIR . '</code>' ) . '</p></div>';
|
68 |
-
}
|
69 |
-
add_action( 'admin_notices', 'hmbkp_path_exists_warning' );
|
70 |
-
|
71 |
-
endif;
|
72 |
-
|
73 |
-
// If the backups directory exists but isn't writable
|
74 |
-
if ( is_dir( hmbkp_path() ) && ! is_writable( hmbkp_path() ) ) :
|
75 |
-
|
76 |
-
function hmbkp_writable_path_warning() {
|
77 |
-
$php_user = exec( 'whoami' );
|
78 |
-
$php_group = reset( explode( ' ', exec( 'groups' ) ) );
|
79 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress is almost ready.', 'hmbkp' ) . '</strong> ' . sprintf( __( 'Your backups directory isn\'t writable, run %1$s or %2$s or set the permissions yourself.', 'hmbkp' ), '<code>chown -R ' . $php_user . ':' . $php_group . ' ' . hmbkp_path() . '</code>', '<code>chmod -R 777 ' . hmbkp_path() . '</code>' ) . '</p></div>';
|
80 |
-
}
|
81 |
-
add_action( 'admin_notices', 'hmbkp_writable_path_warning' );
|
82 |
-
|
83 |
-
endif;
|
84 |
-
|
85 |
-
// If safe mode is active
|
86 |
-
if ( hmbkp_is_safe_mode_active() ) :
|
87 |
-
|
88 |
-
function hmbkp_safe_mode_warning() {
|
89 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( '%1$s is running in %2$s. Please contact your host and ask them to disable %3$s.', 'hmbkp' ), '<code>PHP</code>', sprintf( '<a href="%1$s">%2$s</a>', __( 'http://php.net/manual/en/features.safe-mode.php', 'hmbkp' ), __( 'Safe Mode', 'hmbkp' ) ), '<code>' . __( 'Safe Mode', 'hmbkp' ) . '</code>' ) . '</p></div>';
|
90 |
-
}
|
91 |
-
add_action( 'admin_notices', 'hmbkp_safe_mode_warning' );
|
92 |
-
|
93 |
-
endif;
|
94 |
-
|
95 |
-
// If both HMBKP_FILES_ONLY & HMBKP_DATABASE_ONLY are defined at the same time
|
96 |
-
if ( hmbkp_get_files_only() && hmbkp_get_database_only() ) :
|
97 |
-
|
98 |
-
function hmbkp_nothing_to_backup_warning() {
|
99 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( 'You have both %1$s and %2$s defined so there isn\'t anything to back up.', 'hmbkp' ), '<code>HMBKP_DATABASE_ONLY</code>', '<code>HMBKP_FILES_ONLY</code>' ) . '</p></div>';
|
100 |
-
}
|
101 |
-
add_action( 'admin_notices', 'hmbkp_nothing_to_backup_warning' );
|
102 |
-
|
103 |
-
endif;
|
104 |
-
|
105 |
-
// If the email address is invalid
|
106 |
-
if ( hmbkp_get_email_address() && array_diff( hmbkp_get_email_address(), array_filter( hmbkp_get_email_address(), 'is_email' ) ) ) :
|
107 |
-
|
108 |
-
function hmbkp_email_invalid_warning() {
|
109 |
-
$invalid_emails = array_diff( hmbkp_get_email_address(), array_filter( hmbkp_get_email_address(), 'is_email' ) );
|
110 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( _n( 'The following email address is not valid: %s.', 'The following email addresses are not valid: %s.', count( $invalid_emails ), 'hmbkp' ), '<code>' . implode( '</code>, <code>', $invalid_emails ) . '</code>' ) . '</p></div>';
|
111 |
-
}
|
112 |
-
add_action( 'admin_notices', 'hmbkp_email_invalid_warning' );
|
113 |
-
|
114 |
-
endif;
|
115 |
-
|
116 |
-
// If the email failed to send
|
117 |
-
if ( hmbkp_get_email_address() && get_option( 'hmbkp_email_error' ) ) :
|
118 |
-
|
119 |
-
function hmbkp_email_failed_warning() {
|
120 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . __( 'The last backup email failed to send. It\'s likely that the file is too large.', 'hmbkp' ) . '</p></div>';
|
121 |
-
}
|
122 |
-
add_action( 'admin_notices', 'hmbkp_email_failed_warning' );
|
123 |
-
|
124 |
-
endif;
|
125 |
-
|
126 |
-
// If a custom backups directory is defined and it doesn't exist and can't be created
|
127 |
-
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH && ! is_dir( HMBKP_PATH ) ) :
|
128 |
-
|
129 |
-
function hmbkp_custom_path_exists_warning() {
|
130 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( 'Your custom backups directory %1$s doesn\'t exist and can\'t be created, your backups will be saved to %2$s instead.', 'hmbkp' ), '<code>' . HMBKP_PATH . '</code>', '<code>' . hmbkp_path() . '</code>' ) . '</p></div>';
|
131 |
-
}
|
132 |
-
add_action( 'admin_notices', 'hmbkp_custom_path_exists_warning' );
|
133 |
-
|
134 |
-
endif;
|
135 |
-
|
136 |
-
// If a custom backups directory is defined and exists but isn't writable
|
137 |
-
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH && is_dir( HMBKP_PATH ) && ! is_writable( HMBKP_PATH ) ) :
|
138 |
-
|
139 |
-
function hmbkp_custom_path_writable_notice() {
|
140 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( 'Your custom backups directory %1$s isn\'t writable, new backups will be saved to %2$s instead.', 'hmbkp' ), '<code>' . HMBKP_PATH . '</code>', '<code>' . hmbkp_path() . '</code>' ) . '</p></div>';
|
141 |
-
}
|
142 |
-
add_action( 'admin_notices', 'hmbkp_custom_path_writable_notice' );
|
143 |
-
|
144 |
-
endif;
|
145 |
-
|
146 |
-
// If there are custom excludes defined and any of the files or directories don't exist
|
147 |
-
if ( hmbkp_invalid_custom_excludes() ) :
|
148 |
-
|
149 |
-
function hmbkp_invalid_exclude_notice() {
|
150 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( 'You have defined a custom exclude list but the following paths don\'t exist %s, are you sure you entered them correctly?', 'hmbkp' ), '<code>' . implode( '</code>, <code>', (array) hmbkp_invalid_custom_excludes() ) . '</code>' ) . '</p></div>';
|
151 |
-
}
|
152 |
-
add_action( 'admin_notices', 'hmbkp_invalid_exclude_notice' );
|
153 |
-
|
154 |
-
endif;
|
155 |
-
|
156 |
-
// If there are any errors reported in the backup
|
157 |
-
if ( hmbkp_backup_errors_message() ) :
|
158 |
-
|
159 |
-
function hmbkp_backup_errors_notice() {
|
160 |
-
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress detected issues with your last backup.', 'hmbkp' ) . '</strong><a href="' . add_query_arg( 'action', 'hmbkp_dismiss_error' ) . '" style="float: right;" class="button">Dismiss</a></p>' . hmbkp_backup_errors_message() . '</div>';
|
161 |
-
}
|
162 |
-
add_action( 'admin_notices', 'hmbkp_backup_errors_notice' );
|
163 |
-
|
164 |
-
endif;
|
165 |
-
|
166 |
-
}
|
167 |
-
add_action( 'admin_head', 'hmbkp_admin_notices' );
|
168 |
-
|
169 |
-
/**
|
170 |
-
* Hook in an change the plugin description when BackUpWordPress is activated
|
171 |
-
*
|
172 |
-
* @param array $plugins
|
173 |
-
* @return $plugins
|
174 |
-
*/
|
175 |
-
function hmbkp_plugin_row( $plugins ) {
|
176 |
-
|
177 |
-
if ( isset( $plugins[HMBKP_PLUGIN_SLUG . '/plugin.php'] ) )
|
178 |
-
$plugins[HMBKP_PLUGIN_SLUG . '/plugin.php']['Description'] = str_replace( 'Once activated you\'ll find me under <strong>Tools → Backups</strong>', 'Find me under <strong><a href="' . admin_url( 'tools.php?page=' . HMBKP_PLUGIN_SLUG ) . '">Tools → Backups</a></strong>', $plugins[HMBKP_PLUGIN_SLUG . '/plugin.php']['Description'] );
|
179 |
-
|
180 |
-
return $plugins;
|
181 |
-
|
182 |
-
}
|
183 |
-
add_filter( 'all_plugins', 'hmbkp_plugin_row', 10 );
|
184 |
-
|
185 |
-
/**
|
186 |
-
* Parse the json string of errors and
|
187 |
-
* output as a human readable message
|
188 |
-
*
|
189 |
-
* @access public
|
190 |
-
* @return null
|
191 |
-
*/
|
192 |
-
function hmbkp_backup_errors_message() {
|
193 |
-
|
194 |
-
$message = '';
|
195 |
-
|
196 |
-
foreach ( (array) json_decode( hmbkp_backup_errors() ) as $key => $errors )
|
197 |
-
foreach ( $errors as $error )
|
198 |
-
$message .= '<p><strong>' . $key . '</strong>: <code>' . implode( ':', (array) $error ) . '</code></p>';
|
199 |
-
|
200 |
-
return $message;
|
201 |
-
|
202 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
functions/interface.php
ADDED
@@ -0,0 +1,284 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Displays a row in the manage backups table
|
5 |
+
*
|
6 |
+
* @param string $file
|
7 |
+
*/
|
8 |
+
function hmbkp_get_backup_row( $file, HMBKP_Scheduled_Backup $schedule ) {
|
9 |
+
|
10 |
+
$encoded_file = urlencode( 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 esc_attr( date_i18n( get_option( 'date_format' ) . ' - ' . get_option( 'time_format' ), @filemtime( $file ) + $offset ) ); ?>
|
17 |
+
</th>
|
18 |
+
|
19 |
+
<td class="code">
|
20 |
+
<?php echo esc_attr( HMBKP_Scheduled_Backup::human_filesize( @filesize( $file ) ) ); ?>
|
21 |
+
</td>
|
22 |
+
|
23 |
+
<td><?php echo esc_attr( hmbkp_human_get_type( $file, $schedule ) ); ?></td>
|
24 |
+
|
25 |
+
<td>
|
26 |
+
|
27 |
+
<a href="<?php echo wp_nonce_url( admin_url( 'tools.php?page=' . HMBKP_PLUGIN_SLUG . '&hmbkp_download_backup=' . $encoded_file . '&hmbkp_schedule_id=' . $schedule->get_id() ), 'hmbkp-download_backup' ); ?>"><?php _e( 'Download', 'hmbkp' ); ?></a> |
|
28 |
+
<a href="<?php echo wp_nonce_url( admin_url( 'tools.php?page=' . HMBKP_PLUGIN_SLUG . '&hmbkp_delete_backup=' . $encoded_file . '&hmbkp_schedule_id=' . $schedule->get_id() ), 'hmbkp-delete_backup' ); ?>" class="delete-action"><?php _e( 'Delete', 'hmbkp' ); ?></a>
|
29 |
+
|
30 |
+
</td>
|
31 |
+
|
32 |
+
</tr>
|
33 |
+
|
34 |
+
<?php }
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Displays admin notices for various error / warning
|
38 |
+
* conditions
|
39 |
+
*
|
40 |
+
* @return void
|
41 |
+
*/
|
42 |
+
function hmbkp_admin_notices() {
|
43 |
+
|
44 |
+
// If the backups directory doesn't exist and can't be automatically created
|
45 |
+
if ( ! is_dir( hmbkp_path() ) ) :
|
46 |
+
|
47 |
+
function hmbkp_path_exists_warning() {
|
48 |
+
$php_user = exec( 'whoami' );
|
49 |
+
$php_group = reset( explode( ' ', exec( 'groups' ) ) );
|
50 |
+
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress is almost ready.', 'hmbkp' ) . '</strong> ' . sprintf( __( 'The backups directory can\'t be created because your %1$s directory isn\'t writable, run %2$s or %3$s or create the folder yourself.', 'hmbkp' ), '<code>wp-content</code>', '<code>chown ' . $php_user . ':' . $php_group . ' ' . WP_CONTENT_DIR . '</code>', '<code>chmod 777 ' . WP_CONTENT_DIR . '</code>' ) . '</p></div>';
|
51 |
+
}
|
52 |
+
add_action( 'admin_notices', 'hmbkp_path_exists_warning' );
|
53 |
+
|
54 |
+
endif;
|
55 |
+
|
56 |
+
// If the backups directory exists but isn't writable
|
57 |
+
if ( is_dir( hmbkp_path() ) && ! is_writable( hmbkp_path() ) ) :
|
58 |
+
|
59 |
+
function hmbkp_writable_path_warning() {
|
60 |
+
$php_user = exec( 'whoami' );
|
61 |
+
$php_group = reset( explode( ' ', exec( 'groups' ) ) );
|
62 |
+
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress is almost ready.', 'hmbkp' ) . '</strong> ' . sprintf( __( 'Your backups directory isn\'t writable, run %1$s or %2$s or set the permissions yourself.', 'hmbkp' ), '<code>chown -R ' . esc_attr( $php_user ) . ':' . esc_attr( $php_group ) . ' ' . esc_attr( hmbkp_path() ) . '</code>', '<code>chmod -R 777 ' . esc_attr( hmbkp_path() ) . '</code>' ) . '</p></div>';
|
63 |
+
}
|
64 |
+
add_action( 'admin_notices', 'hmbkp_writable_path_warning' );
|
65 |
+
|
66 |
+
endif;
|
67 |
+
|
68 |
+
// If safe mode is active
|
69 |
+
if ( HM_Backup::is_safe_mode_active() ) :
|
70 |
+
|
71 |
+
function hmbkp_safe_mode_warning() {
|
72 |
+
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( '%1$s is running in %2$s. Please contact your host and ask them to disable %3$s.', 'hmbkp' ), '<code>PHP</code>', sprintf( '<a href="%1$s">%2$s</a>', __( 'http://php.net/manual/en/features.safe-mode.php', 'hmbkp' ), __( 'Safe Mode', 'hmbkp' ) ), '<code>' . __( 'Safe Mode', 'hmbkp' ) . '</code>' ) . '</p></div>';
|
73 |
+
}
|
74 |
+
add_action( 'admin_notices', 'hmbkp_safe_mode_warning' );
|
75 |
+
|
76 |
+
endif;
|
77 |
+
|
78 |
+
// If a custom backups directory is defined and it doesn't exist and can't be created
|
79 |
+
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH && ! is_dir( HMBKP_PATH ) ) :
|
80 |
+
|
81 |
+
function hmbkp_custom_path_exists_warning() {
|
82 |
+
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( 'Your custom backups directory %1$s doesn\'t exist and can\'t be created, your backups will be saved to %2$s instead.', 'hmbkp' ), '<code>' . esc_attr( HMBKP_PATH ) . '</code>', '<code>' . esc_attr( hmbkp_path() ) . '</code>' ) . '</p></div>';
|
83 |
+
}
|
84 |
+
add_action( 'admin_notices', 'hmbkp_custom_path_exists_warning' );
|
85 |
+
|
86 |
+
endif;
|
87 |
+
|
88 |
+
// If a custom backups directory is defined and exists but isn't writable
|
89 |
+
if ( defined( 'HMBKP_PATH' ) && HMBKP_PATH && is_dir( HMBKP_PATH ) && ! is_writable( HMBKP_PATH ) ) :
|
90 |
+
|
91 |
+
function hmbkp_custom_path_writable_notice() {
|
92 |
+
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress has detected a problem.', 'hmbkp' ) . '</strong> ' . sprintf( __( 'Your custom backups directory %1$s isn\'t writable, new backups will be saved to %2$s instead.', 'hmbkp' ), '<code>' . esc_attr( HMBKP_PATH ) . '</code>', '<code>' . esc_attr( hmbkp_path() ) . '</code>' ) . '</p></div>';
|
93 |
+
}
|
94 |
+
add_action( 'admin_notices', 'hmbkp_custom_path_writable_notice' );
|
95 |
+
|
96 |
+
endif;
|
97 |
+
|
98 |
+
// If there are any errors reported in the backup
|
99 |
+
if ( hmbkp_backup_errors_message() ) :
|
100 |
+
|
101 |
+
function hmbkp_backup_errors_notice() {
|
102 |
+
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress detected issues with your last backup.', 'hmbkp' ) . '</strong><a href="' . add_query_arg( 'action', 'hmbkp_dismiss_error' ) . '" style="float: right;" class="button">Dismiss</a></p>' . hmbkp_backup_errors_message() . '</div>';
|
103 |
+
}
|
104 |
+
add_action( 'admin_notices', 'hmbkp_backup_errors_notice' );
|
105 |
+
|
106 |
+
endif;
|
107 |
+
|
108 |
+
if ( ! empty( $_GET['reason'] ) ) :
|
109 |
+
|
110 |
+
function hmbkp_backup_failed_notice() {
|
111 |
+
echo '<div id="hmbkp-warning" class="updated fade"><p><strong>' . __( 'BackUpWordPress failed to perform the backup.', 'hmbkp' ) . '</strong> ' . __( 'You have likely hit a memory limit.', 'hmbkp' ) . '<a href="' . add_query_arg( 'action', 'hmbkp_dismiss_error' ) . '" style="float: right;" class="button">Dismiss</a></p></div>';
|
112 |
+
}
|
113 |
+
add_action( 'admin_notices', 'hmbkp_backup_failed_notice' );
|
114 |
+
|
115 |
+
endif;
|
116 |
+
|
117 |
+
}
|
118 |
+
add_action( 'admin_head', 'hmbkp_admin_notices' );
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Hook in an change the plugin description when BackUpWordPress is activated
|
122 |
+
*
|
123 |
+
* @param array $plugins
|
124 |
+
* @return $plugins
|
125 |
+
*/
|
126 |
+
function hmbkp_plugin_row( $plugins ) {
|
127 |
+
|
128 |
+
if ( isset( $plugins[HMBKP_PLUGIN_SLUG . '/plugin.php'] ) )
|
129 |
+
$plugins[HMBKP_PLUGIN_SLUG . '/plugin.php']['Description'] = str_replace( 'Once activated you\'ll find me under <strong>Tools → Backups</strong>', 'Find me under <strong><a href="' . admin_url( 'tools.php?page=' . HMBKP_PLUGIN_SLUG ) . '">Tools → Backups</a></strong>', $plugins[HMBKP_PLUGIN_SLUG . '/plugin.php']['Description'] );
|
130 |
+
|
131 |
+
return $plugins;
|
132 |
+
|
133 |
+
}
|
134 |
+
add_filter( 'all_plugins', 'hmbkp_plugin_row', 10 );
|
135 |
+
|
136 |
+
/**
|
137 |
+
* Parse the json string of errors and
|
138 |
+
* output as a human readable message
|
139 |
+
*
|
140 |
+
* @access public
|
141 |
+
* @return null
|
142 |
+
*/
|
143 |
+
function hmbkp_backup_errors_message() {
|
144 |
+
|
145 |
+
$message = '';
|
146 |
+
|
147 |
+
foreach ( (array) json_decode( hmbkp_backup_errors() ) as $key => $errors )
|
148 |
+
foreach ( $errors as $error )
|
149 |
+
$message .= '<p><strong>' . $key . '</strong>: <code>' . implode( ':', (array) $error ) . '</code></p>';
|
150 |
+
|
151 |
+
return $message;
|
152 |
+
|
153 |
+
}
|
154 |
+
|
155 |
+
/**
|
156 |
+
* Display a html list of files
|
157 |
+
*
|
158 |
+
* @param HMBKP_Scheduled_Backup $schedule
|
159 |
+
* @param mixed $excludes (default: null)
|
160 |
+
* @param string $file_method (default: 'get_included_files')
|
161 |
+
* @return void
|
162 |
+
*/
|
163 |
+
function hmbkp_file_list( HMBKP_Scheduled_Backup $schedule, $excludes = null, $file_method = 'get_included_files' ) {
|
164 |
+
|
165 |
+
if ( ! is_null( $excludes ) )
|
166 |
+
$schedule->set_excludes( $excludes );
|
167 |
+
|
168 |
+
$files = $schedule->$file_method();
|
169 |
+
|
170 |
+
if ( $files ) : ?>
|
171 |
+
|
172 |
+
<ul class="hmbkp_file_list code">
|
173 |
+
|
174 |
+
<?php foreach( $files as $file ) :
|
175 |
+
|
176 |
+
if ( ! is_null( $excludes ) && strpos( $file, str_ireplace( $schedule->get_root(), '', $schedule->get_path() ) ) !== false )
|
177 |
+
continue; ?>
|
178 |
+
|
179 |
+
<?php if ( $file->isDir() ) { ?>
|
180 |
+
|
181 |
+
<li title="<?php echo esc_attr( $schedule::conform_dir( trailingslashit( $file->getPathName() ) ) ); ?>"><?php echo trailingslashit( str_ireplace( $schedule::conform_dir( trailingslashit( $schedule->get_root() ) ), '', $schedule::conform_dir( $file->getPathName() ) ) ); ?></li>
|
182 |
+
|
183 |
+
<?php } else { ?>
|
184 |
+
|
185 |
+
<li title="<?php echo esc_attr( $schedule::conform_dir( $file->getPathName() ) ); ?>"><?php echo str_ireplace( $schedule::conform_dir( trailingslashit( $schedule->get_root() ) ), '', $schedule::conform_dir( $file->getPathName() ) ); ?></li>
|
186 |
+
|
187 |
+
<?php }
|
188 |
+
|
189 |
+
endforeach; ?>
|
190 |
+
|
191 |
+
</ul>
|
192 |
+
|
193 |
+
<?php endif;
|
194 |
+
|
195 |
+
}
|
196 |
+
|
197 |
+
|
198 |
+
/**
|
199 |
+
* Get the human readable backup type in.
|
200 |
+
*
|
201 |
+
* @access public
|
202 |
+
* @param string $type
|
203 |
+
* @param HMBKP_Scheduled_Backup $schedule (default: null)
|
204 |
+
* @return string
|
205 |
+
*/
|
206 |
+
function hmbkp_human_get_type( $type, HMBKP_Scheduled_Backup $schedule = null ) {
|
207 |
+
|
208 |
+
if ( strpos( $type, 'complete' ) !== false )
|
209 |
+
return __( 'Database and Files', 'hmbkp' );
|
210 |
+
|
211 |
+
if ( strpos( $type, 'file' ) !== false )
|
212 |
+
return __( 'Files', 'hmbkp' );
|
213 |
+
|
214 |
+
if ( strpos( $type, 'database' ) !== false )
|
215 |
+
return __( 'Database', 'hmbkp' );
|
216 |
+
|
217 |
+
if ( ! is_null( $schedule ) )
|
218 |
+
return hmbkp_human_get_type( $schedule->get_type() );
|
219 |
+
|
220 |
+
return __( 'Legacy', 'hmbkp' );
|
221 |
+
|
222 |
+
}
|
223 |
+
|
224 |
+
|
225 |
+
/**
|
226 |
+
* Display the row of actions for a schedule
|
227 |
+
*
|
228 |
+
* @access public
|
229 |
+
* @param HMBKP_Scheduled_Backup $schedule
|
230 |
+
* @return void
|
231 |
+
*/
|
232 |
+
function hmbkp_schedule_actions( HMBKP_Scheduled_Backup $schedule ) {
|
233 |
+
|
234 |
+
if ( $status = $schedule->get_status() ) { ?>
|
235 |
+
|
236 |
+
<span class="hmbkp-status"><?php echo $status; ?> <a href="<?php echo add_query_arg( array( 'action' => 'hmbkp_cancel', 'hmbkp_schedule_id' => $schedule->get_id() ), HMBKP_ADMIN_URL ); ?>"><?php _e( 'cancel', 'hmbkp' ); ?></a></span>
|
237 |
+
|
238 |
+
<?php } else { ?>
|
239 |
+
|
240 |
+
<div class="hmbkp-schedule-actions row-actions">
|
241 |
+
|
242 |
+
<a class="fancybox" href="<?php echo add_query_arg( array( 'action' => 'hmbkp_edit_schedule_load', 'hmbkp_schedule_id' => $schedule->get_id() ), admin_url( 'admin-ajax.php' ) ); ?>"><?php _e( 'Settings', 'hmbkp' ); ?></a> |
|
243 |
+
|
244 |
+
<?php if ( $schedule->get_type() !== 'database' ) { ?>
|
245 |
+
<a class="fancybox" href="<?php echo add_query_arg( array( 'action' => 'hmbkp_edit_schedule_excludes_load', 'hmbkp_schedule_id' => $schedule->get_id() ), admin_url( 'admin-ajax.php' ) ); ?>"><?php _e( 'Excludes', 'hmbkp' ); ?></a> |
|
246 |
+
<?php } ?>
|
247 |
+
|
248 |
+
<a class="hmbkp-run" href="<?php echo add_query_arg( array( 'action' => 'hmbkp_run_schedule', 'hmbkp_schedule_id' => $schedule->get_id() ), admin_url( 'admin-ajax.php' ) ); ?>"><?php _e( 'Run now', 'hmbkp' ); ?></a> |
|
249 |
+
|
250 |
+
<a class="delete-action" href="<?php echo wp_nonce_url( add_query_arg( array( 'action' => 'hmbkp_delete_schedule', 'hmbkp_schedule_id' => $schedule->get_id() ), HMBKP_ADMIN_URL ), 'hmbkp-delete_schedule' ); ?>"><?php _e( 'Delete', 'hmbkp' ); ?></a>
|
251 |
+
|
252 |
+
</div>
|
253 |
+
|
254 |
+
<?php }
|
255 |
+
|
256 |
+
}
|
257 |
+
|
258 |
+
/**
|
259 |
+
* Load the backup errors file
|
260 |
+
*
|
261 |
+
* @return string
|
262 |
+
*/
|
263 |
+
function hmbkp_backup_errors() {
|
264 |
+
|
265 |
+
if ( ! file_exists( hmbkp_path() . '/.backup_errors' ) )
|
266 |
+
return '';
|
267 |
+
|
268 |
+
return file_get_contents( hmbkp_path() . '/.backup_errors' );
|
269 |
+
|
270 |
+
}
|
271 |
+
|
272 |
+
/**
|
273 |
+
* Load the backup warnings file
|
274 |
+
*
|
275 |
+
* @return string
|
276 |
+
*/
|
277 |
+
function hmbkp_backup_warnings() {
|
278 |
+
|
279 |
+
if ( ! file_exists( hmbkp_path() . '/.backup_warnings' ) )
|
280 |
+
return '';
|
281 |
+
|
282 |
+
return file_get_contents( hmbkp_path() . '/.backup_warnings' );
|
283 |
+
|
284 |
+
}
|
functions/wp-cli.php
DELETED
@@ -1,105 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
|
3 |
-
/**
|
4 |
-
* Implement backup command
|
5 |
-
*
|
6 |
-
* @package wp-cli
|
7 |
-
* @subpackage commands/third-party
|
8 |
-
*/
|
9 |
-
class BackUpCommand extends WP_CLI_Command {
|
10 |
-
|
11 |
-
function __construct( $args, $assoc_args ) {
|
12 |
-
|
13 |
-
// Make sure it's possible to do a backup
|
14 |
-
if ( hmbkp_is_safe_mode_active() ) {
|
15 |
-
WP_CLI::error( 'Backup not possible when php is running safe_mode on' );
|
16 |
-
return false;
|
17 |
-
}
|
18 |
-
|
19 |
-
remove_action( 'hmbkp_backup_started', 'hmbkp_set_status', 10, 0 );
|
20 |
-
remove_action( 'hmbkp_mysqldump_started', 'hmbkp_set_status_dumping_database' );
|
21 |
-
remove_action( 'hmbkp_archive_started', 'hmbkp_set_status_archiving' );
|
22 |
-
|
23 |
-
add_action( 'hmbkp_mysqldump_started', function() {
|
24 |
-
WP_CLI::line( 'Backup: Dumping database...' );
|
25 |
-
} );
|
26 |
-
|
27 |
-
add_action( 'hmbkp_archive_started', function() {
|
28 |
-
WP_CLI::line( 'Backup: Zipping everything up...' );
|
29 |
-
} );
|
30 |
-
|
31 |
-
// Clean up any mess left by a previous backup
|
32 |
-
hmbkp_cleanup();
|
33 |
-
|
34 |
-
$hm_backup = HM_Backup::get_instance();
|
35 |
-
|
36 |
-
if ( ! empty( $assoc_args['path'] ) )
|
37 |
-
$hm_backup->path = $assoc_args['path'];
|
38 |
-
|
39 |
-
if ( ! empty( $assoc_args['root'] ) )
|
40 |
-
$hm_backup->root = $assoc_args['root'];
|
41 |
-
|
42 |
-
if ( ( ! is_dir( $hm_backup->path() ) && ( ! is_writable( dirname( $hm_backup->path() ) ) || ! mkdir( $hm_backup->path() ) ) ) || ! is_writable( $hm_backup->path() ) ) {
|
43 |
-
WP_CLI::error( 'Invalid backup path' );
|
44 |
-
return false;
|
45 |
-
}
|
46 |
-
|
47 |
-
|
48 |
-
if ( ! is_dir( $hm_backup->root() ) || ! is_readable( $hm_backup->root() ) ) {
|
49 |
-
WP_CLI::error( 'Invalid root path' );
|
50 |
-
return false;
|
51 |
-
}
|
52 |
-
|
53 |
-
// Default to both
|
54 |
-
$hm_backup->files_only = false;
|
55 |
-
$hm_backup->database_only = false;
|
56 |
-
|
57 |
-
if ( ! empty( $assoc_args['files_only'] ) )
|
58 |
-
$hm_backup->files_only = true;
|
59 |
-
|
60 |
-
if ( ! empty( $assoc_args['database_only'] ) )
|
61 |
-
$hm_backup->database_only = true;
|
62 |
-
|
63 |
-
if ( ! empty( $assoc_args['mysqldump_command_path'] ) )
|
64 |
-
$hm_backup->mysqldump_command_path = empty( $assoc_args['mysqldump_command_path'] ) || $assoc_args['mysqldump_command_path'] === 'false' ? false : true;
|
65 |
-
|
66 |
-
if ( ! empty( $assoc_args['zip_command_path'] ) )
|
67 |
-
$hm_backup->zip_command_path = empty( $assoc_args['zip_command_path'] ) || $assoc_args['zip_command_path'] === 'false' ? false : true;
|
68 |
-
|
69 |
-
if ( ! empty( $assoc_args['excludes'] ) )
|
70 |
-
$hm_backup->excludes = $valid_rules = array_filter( array_map( 'trim', explode( ',', $assoc_args['excludes'] ) ) );
|
71 |
-
|
72 |
-
$hm_backup->backup();
|
73 |
-
|
74 |
-
WP_CLI::line( 'Backup: Deleting old backups...' );
|
75 |
-
|
76 |
-
// Delete any old backup files
|
77 |
-
hmbkp_delete_old_backups();
|
78 |
-
|
79 |
-
if ( file_exists( HM_Backup::get_instance()->archive_filepath() ) )
|
80 |
-
WP_CLI::success( 'Backup Complete: ' . HM_Backup::get_instance()->archive_filepath() );
|
81 |
-
|
82 |
-
else
|
83 |
-
WP_CLI::error( 'Backup Failed' );
|
84 |
-
|
85 |
-
}
|
86 |
-
|
87 |
-
static function help() {
|
88 |
-
|
89 |
-
WP_CLI::line( <<<EOB
|
90 |
-
usage: wp backup [--files_only] [--database_only] [--path<dir>] [--root<dir>] [--zip_command_path=<path>] [--mysqldump_command_path=<path>]
|
91 |
-
|
92 |
-
--files_only Backup files only, default to off
|
93 |
-
--database_only Backup database only, defaults to off
|
94 |
-
--path dir that the backup should be save in, defaults to wp-content/backups/
|
95 |
-
--root dir that should be backed up, defaults to site root.
|
96 |
-
--zip_command_path path to your zip binary, standard locations are automatically used
|
97 |
-
--mysqldump_command_path path to your mysqldump binary, standard locations are automatically used
|
98 |
-
|
99 |
-
EOB
|
100 |
-
);
|
101 |
-
|
102 |
-
}
|
103 |
-
|
104 |
-
}
|
105 |
-
WP_CLI::addCommand( 'backup', 'BackUpCommand' );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
hm-backup/hm-backup.php
CHANGED
@@ -3,7 +3,7 @@
|
|
3 |
/**
|
4 |
* Generic file and database backup class
|
5 |
*
|
6 |
-
* @version
|
7 |
*/
|
8 |
class HM_Backup {
|
9 |
|
@@ -11,73 +11,65 @@ class HM_Backup {
|
|
11 |
* The path where the backup file should be saved
|
12 |
*
|
13 |
* @string
|
14 |
-
* @access
|
15 |
-
*/
|
16 |
-
public $path;
|
17 |
-
|
18 |
-
/**
|
19 |
-
* Whether the backup should be files only
|
20 |
-
*
|
21 |
-
* @bool
|
22 |
-
* @access public
|
23 |
*/
|
24 |
-
|
25 |
|
26 |
/**
|
27 |
-
*
|
28 |
*
|
29 |
-
* @
|
30 |
-
* @access
|
31 |
*/
|
32 |
-
|
33 |
|
34 |
/**
|
35 |
* The filename of the backup file
|
36 |
*
|
37 |
* @string
|
38 |
-
* @access
|
39 |
*/
|
40 |
-
|
41 |
|
42 |
/**
|
43 |
* The filename of the database dump
|
44 |
*
|
45 |
* @string
|
46 |
-
* @access
|
47 |
*/
|
48 |
-
|
49 |
|
50 |
/**
|
51 |
* The path to the zip command
|
52 |
*
|
53 |
* @string
|
54 |
-
* @access
|
55 |
*/
|
56 |
-
|
57 |
|
58 |
/**
|
59 |
* The path to the mysqldump command
|
60 |
*
|
61 |
* @string
|
62 |
-
* @access
|
63 |
*/
|
64 |
-
|
65 |
|
66 |
/**
|
67 |
* An array of exclude rules
|
68 |
*
|
69 |
* @array
|
70 |
-
* @access
|
71 |
*/
|
72 |
-
|
73 |
|
74 |
/**
|
75 |
* The path that should be backed up
|
76 |
*
|
77 |
* @var string
|
78 |
-
* @access
|
79 |
*/
|
80 |
-
|
81 |
|
82 |
/**
|
83 |
* Holds the current db connection
|
@@ -88,22 +80,31 @@ class HM_Backup {
|
|
88 |
private $db;
|
89 |
|
90 |
/**
|
91 |
-
*
|
|
|
92 |
*
|
93 |
-
* @var
|
94 |
-
* @
|
95 |
-
* @access public
|
96 |
*/
|
97 |
-
private
|
98 |
|
99 |
/**
|
100 |
* An array of all the files in root
|
101 |
-
*
|
102 |
*
|
103 |
* @var array
|
104 |
* @access private
|
105 |
*/
|
106 |
-
private $
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
107 |
|
108 |
/**
|
109 |
* Contains an array of errors
|
@@ -111,7 +112,7 @@ class HM_Backup {
|
|
111 |
* @var mixed
|
112 |
* @access private
|
113 |
*/
|
114 |
-
private $errors;
|
115 |
|
116 |
/**
|
117 |
* Contains an array of warnings
|
@@ -119,7 +120,7 @@ class HM_Backup {
|
|
119 |
* @var mixed
|
120 |
* @access private
|
121 |
*/
|
122 |
-
private $warnings;
|
123 |
|
124 |
/**
|
125 |
* The archive method used
|
@@ -127,7 +128,7 @@ class HM_Backup {
|
|
127 |
* @var string
|
128 |
* @access private
|
129 |
*/
|
130 |
-
private $archive_method;
|
131 |
|
132 |
/**
|
133 |
* The mysqldump method used
|
@@ -135,107 +136,470 @@ class HM_Backup {
|
|
135 |
* @var string
|
136 |
* @access private
|
137 |
*/
|
138 |
-
private $mysqldump_method;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
139 |
|
140 |
/**
|
141 |
* Sets up the default properties
|
142 |
*
|
143 |
* @access public
|
144 |
-
* @return null
|
145 |
*/
|
146 |
public function __construct() {
|
147 |
|
148 |
-
// Raise the memory limit and
|
149 |
@ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
|
150 |
@set_time_limit( 0 );
|
151 |
|
152 |
-
|
153 |
-
|
154 |
set_error_handler( array( &$this, 'error_handler' ) );
|
155 |
|
156 |
-
|
157 |
-
$this->root = $this->conform_dir( ABSPATH );
|
158 |
|
159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
|
161 |
-
$this->
|
162 |
|
163 |
-
|
164 |
|
165 |
-
|
166 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
167 |
|
168 |
-
$this->
|
169 |
-
$this->files_only = false;
|
170 |
|
171 |
}
|
172 |
|
173 |
/**
|
174 |
-
*
|
175 |
*
|
176 |
* @access public
|
177 |
-
* @
|
178 |
-
* @return object
|
179 |
*/
|
180 |
-
public
|
|
|
|
|
|
|
181 |
|
182 |
-
if (
|
183 |
-
|
184 |
|
185 |
-
|
186 |
|
187 |
}
|
188 |
|
189 |
/**
|
190 |
-
*
|
191 |
*
|
192 |
* @access public
|
193 |
* @return string
|
194 |
*/
|
195 |
-
public function
|
196 |
-
|
|
|
|
|
197 |
}
|
198 |
|
199 |
/**
|
200 |
-
*
|
201 |
*
|
202 |
* @access public
|
203 |
* @return string
|
204 |
*/
|
205 |
-
public function
|
206 |
-
|
|
|
|
|
|
|
|
|
|
|
207 |
}
|
208 |
|
209 |
/**
|
210 |
-
*
|
211 |
*
|
212 |
* @access public
|
213 |
-
* @
|
214 |
*/
|
215 |
-
public function
|
216 |
-
|
217 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
|
219 |
-
public function database_dump_filename() {
|
220 |
-
return strtolower( sanitize_file_name( remove_accents( $this->database_dump_filename ) ) );
|
221 |
}
|
222 |
|
223 |
-
|
224 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
225 |
}
|
226 |
|
227 |
-
|
228 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
229 |
}
|
230 |
|
231 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
232 |
return $this->archive_method;
|
233 |
}
|
234 |
|
235 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
236 |
return $this->mysqldump_method;
|
237 |
}
|
238 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
239 |
/**
|
240 |
* Kick off a backup
|
241 |
*
|
@@ -244,16 +608,16 @@ class HM_Backup {
|
|
244 |
*/
|
245 |
public function backup() {
|
246 |
|
247 |
-
do_action( 'hmbkp_backup_started'
|
248 |
|
249 |
// Backup database
|
250 |
-
if (
|
251 |
-
$this->
|
252 |
|
253 |
// Zip everything up
|
254 |
$this->archive();
|
255 |
|
256 |
-
do_action( 'hmbkp_backup_complete'
|
257 |
|
258 |
}
|
259 |
|
@@ -264,62 +628,64 @@ class HM_Backup {
|
|
264 |
* if not.
|
265 |
*
|
266 |
* @access public
|
267 |
-
* @return null
|
268 |
*/
|
269 |
-
public function
|
270 |
|
271 |
-
do_action( 'hmbkp_mysqldump_started' );
|
272 |
|
273 |
-
$this->
|
|
|
274 |
|
275 |
-
|
276 |
-
|
277 |
|
278 |
-
|
279 |
-
$port = strpos( DB_HOST, ':' ) ? end( explode( ':', DB_HOST ) ) : '';
|
280 |
|
281 |
-
|
282 |
-
$cmd = escapeshellarg( $this->mysqldump_command_path );
|
283 |
|
284 |
-
|
285 |
-
$cmd .= ' --no-create-db';
|
286 |
|
287 |
-
|
288 |
-
$cmd .= ' --hex-blob';
|
289 |
|
290 |
-
|
291 |
-
|
292 |
|
293 |
-
|
294 |
-
|
295 |
-
$cmd .= ' -p' . escapeshellarg( DB_PASSWORD );
|
296 |
|
297 |
-
|
298 |
-
|
299 |
|
300 |
-
|
301 |
-
|
302 |
-
$cmd .= ' -P ' . $port;
|
303 |
|
304 |
-
|
305 |
-
|
306 |
|
307 |
-
|
308 |
-
|
|
|
309 |
|
310 |
-
|
311 |
-
|
312 |
|
313 |
-
|
314 |
-
|
|
|
315 |
|
316 |
-
|
|
|
317 |
|
318 |
-
//
|
319 |
-
|
320 |
-
|
|
|
|
|
321 |
|
322 |
-
|
|
|
|
|
|
|
323 |
|
324 |
}
|
325 |
|
@@ -327,11 +693,10 @@ class HM_Backup {
|
|
327 |
* PHP mysqldump fallback functions, exports the database to a .sql file
|
328 |
*
|
329 |
* @access public
|
330 |
-
* @return null
|
331 |
*/
|
332 |
public function mysqldump_fallback() {
|
333 |
|
334 |
-
$this->errors_to_warnings( $this->
|
335 |
|
336 |
$this->mysqldump_method = 'mysqldump_fallback';
|
337 |
|
@@ -369,18 +734,17 @@ class HM_Backup {
|
|
369 |
* Zip up all the files.
|
370 |
*
|
371 |
* Attempts to use the shell zip command, if
|
372 |
-
* thats not available then it
|
373 |
* PHP ZipArchive and finally PclZip.
|
374 |
*
|
375 |
* @access public
|
376 |
-
* @return null
|
377 |
*/
|
378 |
public function archive() {
|
379 |
|
380 |
-
do_action( 'hmbkp_archive_started' );
|
381 |
|
382 |
// Do we have the path to the zip command
|
383 |
-
if ( $this->
|
384 |
$this->zip();
|
385 |
|
386 |
// If not or if the shell zip failed then use ZipArchive
|
@@ -392,10 +756,10 @@ class HM_Backup {
|
|
392 |
$this->pcl_zip();
|
393 |
|
394 |
// Delete the database dump file
|
395 |
-
if ( file_exists( $this->
|
396 |
-
unlink( $this->
|
397 |
|
398 |
-
do_action( 'hmbkp_archive_finished' );
|
399 |
|
400 |
}
|
401 |
|
@@ -403,31 +767,30 @@ class HM_Backup {
|
|
403 |
* Zip using the native zip command
|
404 |
*
|
405 |
* @access public
|
406 |
-
* @return null
|
407 |
*/
|
408 |
public function zip() {
|
409 |
|
410 |
$this->archive_method = 'zip';
|
411 |
|
412 |
// Zip up $this->root with excludes
|
413 |
-
if (
|
414 |
-
$this->warning( $this->archive_method, shell_exec( 'cd ' . escapeshellarg( $this->
|
415 |
|
416 |
// Zip up $this->root without excludes
|
417 |
-
elseif (
|
418 |
-
$this->warning( $this->archive_method, shell_exec( 'cd ' . escapeshellarg( $this->
|
419 |
|
420 |
// Add the database dump to the archive
|
421 |
-
if (
|
422 |
-
$this->warning( $this->archive_method, shell_exec( 'cd ' . escapeshellarg( $this->
|
423 |
|
424 |
-
$this->
|
425 |
|
426 |
}
|
427 |
|
428 |
/**
|
429 |
* Fallback for creating zip archives if zip command is
|
430 |
-
*
|
431 |
*
|
432 |
* @access public
|
433 |
* @param string $path
|
@@ -439,23 +802,32 @@ class HM_Backup {
|
|
439 |
|
440 |
$zip = new ZipArchive();
|
441 |
|
442 |
-
if ( ! class_exists( 'ZipArchive' ) || ! $zip->open( $this->
|
443 |
return;
|
444 |
|
445 |
-
|
|
|
|
|
446 |
|
447 |
$files_added = 0;
|
448 |
|
449 |
-
foreach ( $this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
450 |
|
451 |
-
if (
|
452 |
-
$zip->addEmptyDir( trailingslashit( $file ) );
|
453 |
|
454 |
-
elseif (
|
455 |
-
$zip->addFile( trailingslashit( $this->
|
456 |
|
457 |
if ( ++$files_added % 500 === 0 )
|
458 |
-
if ( ! $zip->close() || ! $zip->open( $this->
|
459 |
return;
|
460 |
|
461 |
}
|
@@ -463,8 +835,8 @@ class HM_Backup {
|
|
463 |
}
|
464 |
|
465 |
// Add the database
|
466 |
-
if (
|
467 |
-
$zip->addFile( $this->
|
468 |
|
469 |
if ( $zip->status )
|
470 |
$this->warning( $this->archive_method, $zip->status );
|
@@ -474,13 +846,13 @@ class HM_Backup {
|
|
474 |
|
475 |
$zip->close();
|
476 |
|
477 |
-
$this->
|
478 |
|
479 |
}
|
480 |
|
481 |
/**
|
482 |
* Fallback for creating zip archives if zip command and ZipArchive are
|
483 |
-
*
|
484 |
*
|
485 |
* Uses the PclZip library that ships with WordPress
|
486 |
*
|
@@ -498,21 +870,38 @@ class HM_Backup {
|
|
498 |
|
499 |
$this->load_pclzip();
|
500 |
|
501 |
-
$archive = new PclZip( $this->
|
502 |
|
503 |
// Zip up everything
|
504 |
-
if (
|
505 |
-
if ( ! $archive->add( $this->
|
506 |
$this->warning( $this->archive_method, $archive->errorInfo( true ) );
|
507 |
|
508 |
// Add the database
|
509 |
-
if (
|
510 |
-
if ( ! $archive->add( $this->
|
511 |
$this->warning( $this->archive_method, $archive->errorInfo( true ) );
|
512 |
|
513 |
unset( $GLOBALS['_hmbkp_exclude_string'] );
|
514 |
|
515 |
-
$this->
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
516 |
|
517 |
}
|
518 |
|
@@ -522,85 +911,57 @@ class HM_Backup {
|
|
522 |
* @access public
|
523 |
* @return bool
|
524 |
*/
|
525 |
-
public function
|
526 |
|
527 |
// If we've already passed then no need to check again
|
528 |
if ( ! empty( $this->archive_verified ) )
|
529 |
return true;
|
530 |
|
531 |
-
if ( ! file_exists( $this->
|
532 |
-
$this->error( $this->
|
533 |
|
534 |
// Verify using the zip command if possible
|
535 |
-
if ( $this->
|
536 |
|
537 |
-
$verify = shell_exec( escapeshellarg( $this->
|
538 |
|
539 |
if ( strpos( $verify, 'OK' ) === false )
|
540 |
-
$this->error( $this->
|
541 |
|
542 |
}
|
543 |
|
544 |
// If there are errors delete the backup file.
|
545 |
-
if ( $this->
|
546 |
-
unlink( $this->
|
547 |
|
548 |
-
if ( $this->
|
549 |
return false;
|
550 |
|
|
|
|
|
|
|
551 |
return $this->archive_verified = true;
|
552 |
|
553 |
}
|
554 |
|
555 |
/**
|
556 |
-
*
|
557 |
-
* root, ignored unreadable files and excludes
|
558 |
*
|
559 |
* @access public
|
560 |
* @return array
|
561 |
*/
|
562 |
-
public function
|
563 |
|
564 |
if ( ! empty( $this->files ) )
|
565 |
return $this->files;
|
566 |
|
567 |
$this->files = array();
|
568 |
|
569 |
-
if ( defined( 'RecursiveDirectoryIterator::FOLLOW_SYMLINKS' ) )
|
570 |
-
|
571 |
-
$filesystem = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $this->root(), RecursiveDirectoryIterator::FOLLOW_SYMLINKS ), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD );
|
572 |
-
|
573 |
-
$excludes = $this->exclude_string( 'regex' );
|
574 |
-
|
575 |
-
foreach ( $filesystem as $file ) {
|
576 |
-
|
577 |
-
if ( ! $file->isReadable() ) {
|
578 |
-
$this->unreadable_files[] = $file->getPathName();
|
579 |
-
continue;
|
580 |
-
}
|
581 |
-
|
582 |
-
$pathname = str_ireplace( trailingslashit( $this->root() ), '', $this->conform_dir( $file->getPathname() ) );
|
583 |
-
|
584 |
-
// Excludes
|
585 |
-
if ( $excludes && preg_match( '(' . $excludes . ')', $pathname ) )
|
586 |
-
continue;
|
587 |
-
|
588 |
-
// Don't include database dump as it's added separately
|
589 |
-
if ( basename( $pathname ) == $this->database_dump_filename() )
|
590 |
-
continue;
|
591 |
-
|
592 |
-
$this->files[] = $pathname;
|
593 |
-
|
594 |
-
}
|
595 |
-
|
596 |
-
} else {
|
597 |
|
598 |
-
|
599 |
-
|
600 |
-
}
|
601 |
-
|
602 |
-
if ( ! empty( $this->unreadable_files ) )
|
603 |
-
$this->warning( $this->archive_method(), __( 'The following files are unreadable and couldn\'t be backed up: ', 'hmbkp' ) . implode( ', ', $this->unreadable_files ) );
|
604 |
|
605 |
return $this->files;
|
606 |
|
@@ -613,11 +974,11 @@ class HM_Backup {
|
|
613 |
* Used if RecursiveDirectoryIterator::FOLLOW_SYMLINKS isn't available
|
614 |
*
|
615 |
* @access private
|
616 |
-
* @param
|
617 |
* @param array $files. (default: array())
|
618 |
* @return array
|
619 |
*/
|
620 |
-
private function
|
621 |
|
622 |
$handle = opendir( $dir );
|
623 |
|
@@ -626,25 +987,16 @@ class HM_Backup {
|
|
626 |
while ( $file = readdir( $handle ) ) :
|
627 |
|
628 |
// Ignore current dir and containing dir and any unreadable files or directories
|
629 |
-
if ( $file
|
630 |
continue;
|
631 |
|
632 |
$filepath = $this->conform_dir( trailingslashit( $dir ) . $file );
|
633 |
-
$file = str_ireplace( trailingslashit( $this->
|
634 |
|
635 |
-
|
636 |
-
$this->unreadable_files[] = $filepath;
|
637 |
-
continue;
|
638 |
-
}
|
639 |
-
|
640 |
-
// Skip the backups dir and any excluded paths
|
641 |
-
if ( ( $excludes && preg_match( '(' . $excludes . ')', $file ) ) )
|
642 |
-
continue;
|
643 |
-
|
644 |
-
$files[] = $file;
|
645 |
|
646 |
if ( is_dir( $filepath ) )
|
647 |
-
$files = $this->
|
648 |
|
649 |
endwhile;
|
650 |
|
@@ -652,84 +1004,144 @@ class HM_Backup {
|
|
652 |
|
653 |
}
|
654 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
655 |
private function load_pclzip() {
|
656 |
|
657 |
// Load PclZip
|
658 |
if ( ! defined( 'PCLZIP_TEMPORARY_DIR' ) )
|
659 |
-
define( 'PCLZIP_TEMPORARY_DIR', trailingslashit( $this->
|
660 |
|
661 |
require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
|
662 |
|
663 |
}
|
664 |
|
665 |
/**
|
666 |
-
*
|
|
|
|
|
667 |
*
|
668 |
* @access public
|
669 |
-
* @return
|
670 |
*/
|
671 |
-
public function
|
672 |
-
|
673 |
-
if ( ! $this->shell_exec_available() )
|
674 |
-
return '';
|
675 |
|
676 |
-
|
677 |
-
$mysqldump_locations = array(
|
678 |
-
'/usr/local/bin/mysqldump',
|
679 |
-
'/usr/local/mysql/bin/mysqldump',
|
680 |
-
'/usr/mysql/bin/mysqldump',
|
681 |
-
'/usr/bin/mysqldump',
|
682 |
-
'/opt/local/lib/mysql6/bin/mysqldump',
|
683 |
-
'/opt/local/lib/mysql5/bin/mysqldump',
|
684 |
-
'/opt/local/lib/mysql4/bin/mysqldump',
|
685 |
-
'/xampp/mysql/bin/mysqldump',
|
686 |
-
'/Program Files/xampp/mysql/bin/mysqldump',
|
687 |
-
'/Program Files/MySQL/MySQL Server 6.0/bin/mysqldump',
|
688 |
-
'/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump',
|
689 |
-
'/Program Files/MySQL/MySQL Server 5.4/bin/mysqldump',
|
690 |
-
'/Program Files/MySQL/MySQL Server 5.1/bin/mysqldump',
|
691 |
-
'/Program Files/MySQL/MySQL Server 5.0/bin/mysqldump',
|
692 |
-
'/Program Files/MySQL/MySQL Server 4.1/bin/mysqldump'
|
693 |
-
);
|
694 |
|
695 |
-
if (
|
696 |
-
|
697 |
|
698 |
-
//
|
699 |
-
|
700 |
-
|
701 |
-
return $location;
|
702 |
|
703 |
-
return
|
704 |
|
705 |
}
|
706 |
|
707 |
/**
|
708 |
-
*
|
709 |
*
|
710 |
* @access public
|
711 |
-
* @
|
|
|
712 |
*/
|
713 |
-
public function
|
714 |
|
715 |
-
|
716 |
-
|
717 |
-
return '';
|
718 |
-
|
719 |
-
// List of possible zip locations
|
720 |
-
$zip_locations = array(
|
721 |
-
'/usr/bin/zip'
|
722 |
-
);
|
723 |
|
724 |
-
if (
|
725 |
-
|
726 |
|
727 |
-
|
728 |
-
foreach ( $zip_locations as $location )
|
729 |
-
if ( @file_exists( $this->conform_dir( $location ) ) )
|
730 |
-
return $location;
|
731 |
-
|
732 |
-
return '';
|
733 |
|
734 |
}
|
735 |
|
@@ -743,30 +1155,25 @@ class HM_Backup {
|
|
743 |
* @param string $context. (default: 'zip')
|
744 |
* @return string
|
745 |
*/
|
746 |
-
|
747 |
|
748 |
// Return a comma separated list by default
|
749 |
$separator = ', ';
|
750 |
$wildcard = '';
|
751 |
|
752 |
// The zip command
|
753 |
-
if ( $context
|
754 |
$wildcard = '*';
|
755 |
$separator = ' -x ';
|
756 |
|
757 |
// The PclZip fallback library
|
758 |
-
} elseif ( $context
|
759 |
$wildcard = '([\s\S]*?)';
|
760 |
$separator = '|';
|
761 |
|
762 |
}
|
763 |
|
764 |
-
|
765 |
-
$excludes = array_filter( array_unique( array_map( 'trim', (array) $this->excludes ) ) );
|
766 |
-
|
767 |
-
// If path() is inside root(), exclude it
|
768 |
-
if ( strpos( $this->path(), $this->root() ) !== false )
|
769 |
-
$excludes[] = trailingslashit( $this->path() );
|
770 |
|
771 |
foreach( $excludes as $key => &$rule ) {
|
772 |
|
@@ -785,40 +1192,40 @@ class HM_Backup {
|
|
785 |
$fragment = true;
|
786 |
|
787 |
// Strip $this->root and conform
|
788 |
-
$rule = str_ireplace( $this->
|
789 |
|
790 |
// Strip the preceeding slash
|
791 |
if ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) )
|
792 |
$rule = substr( $rule, 1 );
|
793 |
|
794 |
// Escape string for regex
|
795 |
-
if ( $context
|
796 |
$rule = str_replace( '.', '\.', $rule );
|
797 |
|
798 |
// Convert any existing wildcards
|
799 |
-
if ( $wildcard
|
800 |
$rule = str_replace( '*', $wildcard, $rule );
|
801 |
|
802 |
// Wrap directory fragments and files in wildcards for zip
|
803 |
-
if ( $context
|
804 |
$rule = $wildcard . $rule . $wildcard;
|
805 |
|
806 |
// Add a wildcard to the end of absolute url for zips
|
807 |
-
if ( $context
|
808 |
$rule .= $wildcard;
|
809 |
|
810 |
// Add and end carrot to files for pclzip but only if it doesn't end in a wildcard
|
811 |
-
if ( $file && $context
|
812 |
$rule .= '$';
|
813 |
|
814 |
// Add a start carrot to absolute urls for pclzip
|
815 |
-
if ( $absolute && $context
|
816 |
$rule = '^' . $rule;
|
817 |
|
818 |
}
|
819 |
|
820 |
// Escape shell args for zip command
|
821 |
-
if ( $context
|
822 |
$excludes = array_map( 'escapeshellarg', array_unique( $excludes ) );
|
823 |
|
824 |
return implode( $separator, $excludes );
|
@@ -826,83 +1233,14 @@ class HM_Backup {
|
|
826 |
}
|
827 |
|
828 |
/**
|
829 |
-
*
|
830 |
-
*
|
831 |
-
* @access private
|
832 |
-
* @return bool
|
833 |
-
*/
|
834 |
-
public function is_safe_mode_active() {
|
835 |
-
|
836 |
-
if ( $safe_mode = ini_get( 'safe_mode' ) && strtolower( $safe_mode ) != 'off' )
|
837 |
-
return true;
|
838 |
-
|
839 |
-
return false;
|
840 |
-
|
841 |
-
}
|
842 |
-
|
843 |
-
/**
|
844 |
-
* Check whether shell_exec has been disabled.
|
845 |
-
*
|
846 |
-
* @access private
|
847 |
-
* @return bool
|
848 |
-
*/
|
849 |
-
private function shell_exec_available() {
|
850 |
-
|
851 |
-
// Are we in Safe Mode
|
852 |
-
if ( $this->is_safe_mode_active() )
|
853 |
-
return false;
|
854 |
-
|
855 |
-
// Is shell_exec disabled?
|
856 |
-
if ( in_array( 'shell_exec', array_map( 'trim', explode( ',', ini_get( 'disable_functions' ) ) ) ) )
|
857 |
-
return false;
|
858 |
-
|
859 |
-
// Can we issue a simple echo command?
|
860 |
-
if ( ! @shell_exec( 'echo backupwordpress' ) )
|
861 |
-
return false;
|
862 |
-
|
863 |
-
return true;
|
864 |
-
|
865 |
-
}
|
866 |
-
|
867 |
-
/**
|
868 |
-
* Sanitize a directory path
|
869 |
-
*
|
870 |
-
* @access public
|
871 |
-
* @param string $dir
|
872 |
-
* @param bool $rel. (default: false)
|
873 |
-
* @return string $dir
|
874 |
-
*/
|
875 |
-
public function conform_dir( $dir, $recursive = false ) {
|
876 |
-
|
877 |
-
// Assume empty dir is root
|
878 |
-
if ( ! $dir )
|
879 |
-
$dir = '/';
|
880 |
-
|
881 |
-
// Replace single forward slash (looks like double slash because we have to escape it)
|
882 |
-
$dir = str_replace( '\\', '/', $dir );
|
883 |
-
$dir = str_replace( '//', '/', $dir );
|
884 |
-
|
885 |
-
// Remove the trailing slash
|
886 |
-
if ( $dir !== '/' )
|
887 |
-
$dir = untrailingslashit( $dir );
|
888 |
-
|
889 |
-
// Carry on until completely normalized
|
890 |
-
if ( ! $recursive && $this->conform_dir( $dir, true ) != $dir )
|
891 |
-
return $this->conform_dir( $dir );
|
892 |
-
|
893 |
-
return (string) $dir;
|
894 |
-
|
895 |
-
}
|
896 |
-
|
897 |
-
/**
|
898 |
-
* Add backquotes to tables and db-names inSQL queries. Taken from phpMyAdmin.
|
899 |
*
|
900 |
* @access private
|
901 |
* @param mixed $a_name
|
902 |
*/
|
903 |
private function sql_backquote( $a_name ) {
|
904 |
|
905 |
-
if ( ! empty( $a_name ) && $a_name
|
906 |
|
907 |
if ( is_array( $a_name ) ) {
|
908 |
|
@@ -1001,7 +1339,7 @@ class HM_Backup {
|
|
1001 |
$field_set[$j] = $this->sql_backquote( mysql_field_name( $result, $j ) );
|
1002 |
$type = mysql_field_type( $result, $j );
|
1003 |
|
1004 |
-
if ( $type
|
1005 |
$field_num[$j] = true;
|
1006 |
|
1007 |
else
|
@@ -1026,7 +1364,7 @@ class HM_Backup {
|
|
1026 |
if ( ! isset($row[$j] ) ) {
|
1027 |
$values[] = 'NULL';
|
1028 |
|
1029 |
-
} elseif ( $row[$j]
|
1030 |
|
1031 |
// a number
|
1032 |
if ( $field_num[$j] )
|
@@ -1045,7 +1383,7 @@ class HM_Backup {
|
|
1045 |
$sql_file .= " \n" . $entries . implode( ', ', $values ) . ") ;";
|
1046 |
|
1047 |
// write the rows in batches of 100
|
1048 |
-
if ( $batch_write
|
1049 |
$batch_write = 0;
|
1050 |
$this->write_sql( $sql_file );
|
1051 |
$sql_file = '';
|
@@ -1099,12 +1437,12 @@ class HM_Backup {
|
|
1099 |
*/
|
1100 |
private function write_sql( $sql ) {
|
1101 |
|
1102 |
-
$sqlname = $this->
|
1103 |
|
1104 |
// Actually write the sql file
|
1105 |
if ( is_writable( $sqlname ) || ! file_exists( $sqlname ) ) {
|
1106 |
|
1107 |
-
if ( ! $handle = fopen( $sqlname, 'a' ) )
|
1108 |
return;
|
1109 |
|
1110 |
if ( ! fwrite( $handle, $sql ) )
|
@@ -1122,9 +1460,8 @@ class HM_Backup {
|
|
1122 |
* Get the errors
|
1123 |
*
|
1124 |
* @access public
|
1125 |
-
* @return null
|
1126 |
*/
|
1127 |
-
public function
|
1128 |
|
1129 |
if ( ! empty( $context ) )
|
1130 |
return isset( $this->errors[$context] ) ? $this->errors[$context] : array();
|
@@ -1133,14 +1470,12 @@ class HM_Backup {
|
|
1133 |
|
1134 |
}
|
1135 |
|
1136 |
-
|
1137 |
/**
|
1138 |
* Add an error to the errors stack
|
1139 |
*
|
1140 |
* @access private
|
1141 |
* @param string $context
|
1142 |
* @param mixed $error
|
1143 |
-
* @return null
|
1144 |
*/
|
1145 |
private function error( $context, $error ) {
|
1146 |
|
@@ -1156,11 +1491,10 @@ class HM_Backup {
|
|
1156 |
*
|
1157 |
* @access private
|
1158 |
* @param string $context. (default: null)
|
1159 |
-
* @return null
|
1160 |
*/
|
1161 |
private function errors_to_warnings( $context = null ) {
|
1162 |
|
1163 |
-
$errors = empty( $context ) ? $this->
|
1164 |
|
1165 |
if ( empty( $errors ) )
|
1166 |
return;
|
@@ -1181,9 +1515,8 @@ class HM_Backup {
|
|
1181 |
* Get the warnings
|
1182 |
*
|
1183 |
* @access public
|
1184 |
-
* @return null
|
1185 |
*/
|
1186 |
-
public function
|
1187 |
|
1188 |
if ( ! empty( $context ) )
|
1189 |
return isset( $this->warnings[$context] ) ? $this->warnings[$context] : array();
|
@@ -1192,14 +1525,12 @@ class HM_Backup {
|
|
1192 |
|
1193 |
}
|
1194 |
|
1195 |
-
|
1196 |
/**
|
1197 |
* Add an warning to the warnings stack
|
1198 |
*
|
1199 |
* @access private
|
1200 |
* @param string $context
|
1201 |
* @param mixed $warning
|
1202 |
-
* @return null
|
1203 |
*/
|
1204 |
private function warning( $context, $warning ) {
|
1205 |
|
@@ -1210,7 +1541,6 @@ class HM_Backup {
|
|
1210 |
|
1211 |
}
|
1212 |
|
1213 |
-
|
1214 |
/**
|
1215 |
* Custom error handler for catching errors
|
1216 |
*
|
@@ -1219,11 +1549,10 @@ class HM_Backup {
|
|
1219 |
* @param string $message
|
1220 |
* @param string $file
|
1221 |
* @param string $line
|
1222 |
-
* @return null
|
1223 |
*/
|
1224 |
public function error_handler( $type ) {
|
1225 |
|
1226 |
-
if ( ( defined( 'E_DEPRECATED' ) && $type
|
1227 |
return false;
|
1228 |
|
1229 |
$args = func_get_args();
|
3 |
/**
|
4 |
* Generic file and database backup class
|
5 |
*
|
6 |
+
* @version 2.0 RC1
|
7 |
*/
|
8 |
class HM_Backup {
|
9 |
|
11 |
* The path where the backup file should be saved
|
12 |
*
|
13 |
* @string
|
14 |
+
* @access private
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 |
*/
|
16 |
+
private $path = '';
|
17 |
|
18 |
/**
|
19 |
+
* The backup type, must be either complete, file or database
|
20 |
*
|
21 |
+
* @string
|
22 |
+
* @access private
|
23 |
*/
|
24 |
+
private $type = '';
|
25 |
|
26 |
/**
|
27 |
* The filename of the backup file
|
28 |
*
|
29 |
* @string
|
30 |
+
* @access private
|
31 |
*/
|
32 |
+
private $archive_filename = '';
|
33 |
|
34 |
/**
|
35 |
* The filename of the database dump
|
36 |
*
|
37 |
* @string
|
38 |
+
* @access private
|
39 |
*/
|
40 |
+
private $database_dump_filename = '';
|
41 |
|
42 |
/**
|
43 |
* The path to the zip command
|
44 |
*
|
45 |
* @string
|
46 |
+
* @access private
|
47 |
*/
|
48 |
+
private $zip_command_path;
|
49 |
|
50 |
/**
|
51 |
* The path to the mysqldump command
|
52 |
*
|
53 |
* @string
|
54 |
+
* @access private
|
55 |
*/
|
56 |
+
private $mysqldump_command_path;
|
57 |
|
58 |
/**
|
59 |
* An array of exclude rules
|
60 |
*
|
61 |
* @array
|
62 |
+
* @access private
|
63 |
*/
|
64 |
+
private $excludes = array();
|
65 |
|
66 |
/**
|
67 |
* The path that should be backed up
|
68 |
*
|
69 |
* @var string
|
70 |
+
* @access private
|
71 |
*/
|
72 |
+
private $root = '';
|
73 |
|
74 |
/**
|
75 |
* Holds the current db connection
|
80 |
private $db;
|
81 |
|
82 |
/**
|
83 |
+
* An array of all the files in root
|
84 |
+
* excluding excludes and unreadable files
|
85 |
*
|
86 |
+
* @var array
|
87 |
+
* @access private
|
|
|
88 |
*/
|
89 |
+
private $files = array();
|
90 |
|
91 |
/**
|
92 |
* An array of all the files in root
|
93 |
+
* that match the exclude rules
|
94 |
*
|
95 |
* @var array
|
96 |
* @access private
|
97 |
*/
|
98 |
+
private $excluded_files = array();
|
99 |
+
|
100 |
+
/**
|
101 |
+
* An array of all the files in root
|
102 |
+
* that are unreadable
|
103 |
+
*
|
104 |
+
* @var array
|
105 |
+
* @access private
|
106 |
+
*/
|
107 |
+
private $unreadable_files = array();
|
108 |
|
109 |
/**
|
110 |
* Contains an array of errors
|
112 |
* @var mixed
|
113 |
* @access private
|
114 |
*/
|
115 |
+
private $errors = array();
|
116 |
|
117 |
/**
|
118 |
* Contains an array of warnings
|
120 |
* @var mixed
|
121 |
* @access private
|
122 |
*/
|
123 |
+
private $warnings = array();
|
124 |
|
125 |
/**
|
126 |
* The archive method used
|
128 |
* @var string
|
129 |
* @access private
|
130 |
*/
|
131 |
+
private $archive_method = '';
|
132 |
|
133 |
/**
|
134 |
* The mysqldump method used
|
136 |
* @var string
|
137 |
* @access private
|
138 |
*/
|
139 |
+
private $mysqldump_method = '';
|
140 |
+
|
141 |
+
/**
|
142 |
+
* Check whether safe mode is active or not
|
143 |
+
*
|
144 |
+
* @access public
|
145 |
+
* @static
|
146 |
+
* @return bool
|
147 |
+
*/
|
148 |
+
public static function is_safe_mode_active() {
|
149 |
+
|
150 |
+
if ( ( $safe_mode = @ini_get( 'safe_mode' ) ) && strtolower( $safe_mode ) != 'off' )
|
151 |
+
return true;
|
152 |
+
|
153 |
+
return false;
|
154 |
+
|
155 |
+
}
|
156 |
+
|
157 |
+
/**
|
158 |
+
* Check whether shell_exec has been disabled.
|
159 |
+
*
|
160 |
+
* @access public
|
161 |
+
* @static
|
162 |
+
* @return bool
|
163 |
+
*/
|
164 |
+
public static function is_shell_exec_available() {
|
165 |
+
|
166 |
+
// Are we in Safe Mode
|
167 |
+
if ( self::is_safe_mode_active() )
|
168 |
+
return false;
|
169 |
+
|
170 |
+
// Is shell_exec disabled?
|
171 |
+
if ( in_array( 'shell_exec', array_map( 'trim', explode( ',', @ini_get( 'disable_functions' ) ) ) ) )
|
172 |
+
return false;
|
173 |
+
|
174 |
+
// Can we issue a simple echo command?
|
175 |
+
if ( ! @shell_exec( 'echo backupwordpress' ) )
|
176 |
+
return false;
|
177 |
+
|
178 |
+
return true;
|
179 |
+
|
180 |
+
}
|
181 |
+
|
182 |
+
|
183 |
+
/**
|
184 |
+
* Attempt to work out the root directory of the site, that
|
185 |
+
* is, the path equivelant of home_url().
|
186 |
+
*
|
187 |
+
* @access public
|
188 |
+
* @static
|
189 |
+
* @return string $home_path
|
190 |
+
*/
|
191 |
+
public static function get_home_path() {
|
192 |
+
|
193 |
+
$home = get_option( 'home' );
|
194 |
+
$siteurl = get_option( 'siteurl' );
|
195 |
+
|
196 |
+
$home_path = ABSPATH;
|
197 |
+
|
198 |
+
if ( ! empty( $home ) && $home !== $siteurl )
|
199 |
+
$home_path = trailingslashit( substr( ABSPATH, 0, strrpos( ABSPATH, str_replace( $home, '', $siteurl ) ) ) );
|
200 |
+
|
201 |
+
return self::conform_dir( $home_path );
|
202 |
+
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Sanitize a directory path
|
207 |
+
*
|
208 |
+
* @access public
|
209 |
+
* @static
|
210 |
+
* @param string $dir
|
211 |
+
* @param bool $rel. (default: false)
|
212 |
+
* @return string $dir
|
213 |
+
*/
|
214 |
+
public static function conform_dir( $dir, $recursive = false ) {
|
215 |
+
|
216 |
+
// Assume empty dir is root
|
217 |
+
if ( ! $dir )
|
218 |
+
$dir = '/';
|
219 |
+
|
220 |
+
// Replace single forward slash (looks like double slash because we have to escape it)
|
221 |
+
$dir = str_replace( '\\', '/', $dir );
|
222 |
+
$dir = str_replace( '//', '/', $dir );
|
223 |
+
|
224 |
+
// Remove the trailing slash
|
225 |
+
if ( $dir !== '/' )
|
226 |
+
$dir = untrailingslashit( $dir );
|
227 |
+
|
228 |
+
// Carry on until completely normalized
|
229 |
+
if ( ! $recursive && self::conform_dir( $dir, true ) != $dir )
|
230 |
+
return self::conform_dir( $dir );
|
231 |
+
|
232 |
+
return (string) $dir;
|
233 |
+
|
234 |
+
}
|
235 |
|
236 |
/**
|
237 |
* Sets up the default properties
|
238 |
*
|
239 |
* @access public
|
|
|
240 |
*/
|
241 |
public function __construct() {
|
242 |
|
243 |
+
// Raise the memory limit and max_execution time
|
244 |
@ini_set( 'memory_limit', apply_filters( 'admin_memory_limit', WP_MAX_MEMORY_LIMIT ) );
|
245 |
@set_time_limit( 0 );
|
246 |
|
247 |
+
// Set a custom error handler so we can track errors
|
|
|
248 |
set_error_handler( array( &$this, 'error_handler' ) );
|
249 |
|
250 |
+
}
|
|
|
251 |
|
252 |
+
/**
|
253 |
+
* Get the full filepath to the archive file
|
254 |
+
*
|
255 |
+
* @access public
|
256 |
+
* @return string
|
257 |
+
*/
|
258 |
+
public function get_archive_filepath() {
|
259 |
|
260 |
+
return trailingslashit( $this->get_path() ) . $this->get_archive_filename();
|
261 |
|
262 |
+
}
|
263 |
|
264 |
+
/**
|
265 |
+
* Get the filename of the archive file
|
266 |
+
*
|
267 |
+
* @access public
|
268 |
+
* @return string
|
269 |
+
*/
|
270 |
+
public function get_archive_filename() {
|
271 |
+
|
272 |
+
if ( empty( $this->archive_filename ) )
|
273 |
+
$this->set_archive_filename( implode( '-', array( get_bloginfo( 'name' ), 'backup', date( 'Y-m-d-H-i-s', current_time( 'timestamp' ) ) ) ) . '.zip' );
|
274 |
|
275 |
+
return $this->archive_filename;
|
|
|
276 |
|
277 |
}
|
278 |
|
279 |
/**
|
280 |
+
* Set the filename of the archive file
|
281 |
*
|
282 |
* @access public
|
283 |
+
* @param string $filename
|
|
|
284 |
*/
|
285 |
+
public function set_archive_filename( $filename ) {
|
286 |
+
|
287 |
+
if ( empty( $filename ) || ! is_string( $filename ) )
|
288 |
+
throw new Exception( 'archive filename must be a non empty string' );
|
289 |
|
290 |
+
if ( pathinfo( $filename, PATHINFO_EXTENSION ) !== 'zip' )
|
291 |
+
throw new Exception( 'invalid file extension for archive filename <code>' . $filename . '</code>' );
|
292 |
|
293 |
+
$this->archive_filename = strtolower( sanitize_file_name( remove_accents( $filename ) ) );
|
294 |
|
295 |
}
|
296 |
|
297 |
/**
|
298 |
+
* Get the full filepath to the database dump file.
|
299 |
*
|
300 |
* @access public
|
301 |
* @return string
|
302 |
*/
|
303 |
+
public function get_database_dump_filepath() {
|
304 |
+
|
305 |
+
return trailingslashit( $this->get_path() ) . $this->get_database_dump_filename();
|
306 |
+
|
307 |
}
|
308 |
|
309 |
/**
|
310 |
+
* Get the filename of the database dump file
|
311 |
*
|
312 |
* @access public
|
313 |
* @return string
|
314 |
*/
|
315 |
+
public function get_database_dump_filename() {
|
316 |
+
|
317 |
+
if ( empty( $this->database_dump_filename ) )
|
318 |
+
$this->set_database_dump_filename( 'database_' . DB_NAME . '.sql' );
|
319 |
+
|
320 |
+
return $this->database_dump_filename;
|
321 |
+
|
322 |
}
|
323 |
|
324 |
/**
|
325 |
+
* Set the filename of the database dump file
|
326 |
*
|
327 |
* @access public
|
328 |
+
* @param string $filename
|
329 |
*/
|
330 |
+
public function set_database_dump_filename( $filename ) {
|
331 |
+
|
332 |
+
if ( empty( $filename ) || ! is_string( $filename ) )
|
333 |
+
throw new Exception( 'database dump filename must be a non empty string' );
|
334 |
+
|
335 |
+
if ( pathinfo( $filename, PATHINFO_EXTENSION ) !== 'sql' )
|
336 |
+
throw new Exception( 'invalid file extension for database dump filename <code>' . $filename . '</code>' );
|
337 |
+
|
338 |
+
$this->database_dump_filename = strtolower( sanitize_file_name( remove_accents( $filename ) ) );
|
339 |
|
|
|
|
|
340 |
}
|
341 |
|
342 |
+
/**
|
343 |
+
* Get the root directory to backup from
|
344 |
+
*
|
345 |
+
* Defaults to the root of the path equivalent of your home_url
|
346 |
+
*
|
347 |
+
* @access public
|
348 |
+
* @return string
|
349 |
+
*/
|
350 |
+
public function get_root() {
|
351 |
+
|
352 |
+
if ( empty( $this->root ) )
|
353 |
+
$this->set_root( $this->conform_dir( self::get_home_path() ) );
|
354 |
+
|
355 |
+
return $this->root;
|
356 |
+
|
357 |
}
|
358 |
|
359 |
+
/**
|
360 |
+
* Set the root directory to backup from
|
361 |
+
*
|
362 |
+
* @access public
|
363 |
+
* @param string $path
|
364 |
+
* @return null
|
365 |
+
*/
|
366 |
+
public function set_root( $path ) {
|
367 |
+
|
368 |
+
if ( empty( $path ) || ! is_string( $path ) || ! is_dir ( $path ) )
|
369 |
+
throw new Exception( 'Invalid root path <code>' . $path . '</code> must be a valid directory path' );
|
370 |
+
|
371 |
+
$this->root = $this->conform_dir( $path );
|
372 |
+
|
373 |
+
}
|
374 |
+
|
375 |
+
/**
|
376 |
+
* Get the directory backups are saved to
|
377 |
+
*
|
378 |
+
* @access public
|
379 |
+
* @return string
|
380 |
+
*/
|
381 |
+
public function get_path() {
|
382 |
+
|
383 |
+
if ( empty( $this->path ) )
|
384 |
+
$this->set_path( $this->conform_dir( WP_CONTENT_DIR . '/backups' ) );
|
385 |
+
|
386 |
+
return $this->path;
|
387 |
+
|
388 |
+
}
|
389 |
+
|
390 |
+
/**
|
391 |
+
* Set the directory backups are saved to
|
392 |
+
*
|
393 |
+
* @access public
|
394 |
+
* @param string $path
|
395 |
+
* @return null
|
396 |
+
*/
|
397 |
+
public function set_path( $path ) {
|
398 |
+
|
399 |
+
if ( empty( $path ) || ! is_string( $path ) )
|
400 |
+
throw new Exception( 'Invalid backup path <code>' . $path . '</code> must be a non empty (string)' );
|
401 |
+
|
402 |
+
$this->path = $this->conform_dir( $path );
|
403 |
+
|
404 |
}
|
405 |
|
406 |
+
/**
|
407 |
+
* Get the archive method that was used for the backup
|
408 |
+
*
|
409 |
+
* Will be either zip, ZipArchive or PclZip
|
410 |
+
*
|
411 |
+
* @access public
|
412 |
+
*/
|
413 |
+
public function get_archive_method() {
|
414 |
return $this->archive_method;
|
415 |
}
|
416 |
|
417 |
+
/**
|
418 |
+
* Get the database dump method that was used for the backup
|
419 |
+
*
|
420 |
+
* Will be either mysqldump or mysqldump_fallback
|
421 |
+
*
|
422 |
+
* @access public
|
423 |
+
*/
|
424 |
+
public function get_mysqldump_method() {
|
425 |
return $this->mysqldump_method;
|
426 |
}
|
427 |
|
428 |
+
/**
|
429 |
+
* Get the backup type
|
430 |
+
*
|
431 |
+
* Defaults to complete
|
432 |
+
*
|
433 |
+
* @access public
|
434 |
+
*/
|
435 |
+
public function get_type() {
|
436 |
+
|
437 |
+
if ( empty( $this->type ) )
|
438 |
+
$this->set_type( 'complete' );
|
439 |
+
|
440 |
+
return $this->type;
|
441 |
+
|
442 |
+
}
|
443 |
+
|
444 |
+
/**
|
445 |
+
* Set the backup type
|
446 |
+
*
|
447 |
+
* $type must be one of complete, database or file
|
448 |
+
*
|
449 |
+
* @access public
|
450 |
+
* @param string $type
|
451 |
+
*/
|
452 |
+
public function set_type( $type ) {
|
453 |
+
|
454 |
+
if ( ! is_string( $type ) || ! in_array( $type, array( 'file', 'database', 'complete' ) ) )
|
455 |
+
throw new Exception( 'Invalid backup type <code>' . $type . '</code> must be one of (string) file, database or complete' );
|
456 |
+
|
457 |
+
$this->type = $type;
|
458 |
+
|
459 |
+
}
|
460 |
+
|
461 |
+
/**
|
462 |
+
* Get the path to the mysqldump bin
|
463 |
+
*
|
464 |
+
* If not explicitly set will attempt to work
|
465 |
+
* it out by checking common locations
|
466 |
+
*
|
467 |
+
* @access public
|
468 |
+
* @return string
|
469 |
+
*/
|
470 |
+
public function get_mysqldump_command_path() {
|
471 |
+
|
472 |
+
// Check shell_exec is available
|
473 |
+
if ( ! self::is_shell_exec_available() )
|
474 |
+
return '';
|
475 |
+
|
476 |
+
// Return now if it's already been set
|
477 |
+
if ( isset( $this->mysqldump_command_path ) )
|
478 |
+
return $this->mysqldump_command_path;
|
479 |
+
|
480 |
+
$this->mysqldump_command_path = '';
|
481 |
+
|
482 |
+
// Does mysqldump work
|
483 |
+
if ( is_null( shell_exec( 'hash mysqldump 2>&1' ) ) ) {
|
484 |
+
|
485 |
+
// If so store it for later
|
486 |
+
$this->set_mysqldump_command_path( 'mysqldump' );
|
487 |
+
|
488 |
+
// And return now
|
489 |
+
return $this->mysqldump_command_path;
|
490 |
+
|
491 |
+
}
|
492 |
+
|
493 |
+
// List of possible mysqldump locations
|
494 |
+
$mysqldump_locations = array(
|
495 |
+
'/usr/local/bin/mysqldump',
|
496 |
+
'/usr/local/mysql/bin/mysqldump',
|
497 |
+
'/usr/mysql/bin/mysqldump',
|
498 |
+
'/usr/bin/mysqldump',
|
499 |
+
'/opt/local/lib/mysql6/bin/mysqldump',
|
500 |
+
'/opt/local/lib/mysql5/bin/mysqldump',
|
501 |
+
'/opt/local/lib/mysql4/bin/mysqldump',
|
502 |
+
'/xampp/mysql/bin/mysqldump',
|
503 |
+
'/Program Files/xampp/mysql/bin/mysqldump',
|
504 |
+
'/Program Files/MySQL/MySQL Server 6.0/bin/mysqldump',
|
505 |
+
'/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump',
|
506 |
+
'/Program Files/MySQL/MySQL Server 5.4/bin/mysqldump',
|
507 |
+
'/Program Files/MySQL/MySQL Server 5.1/bin/mysqldump',
|
508 |
+
'/Program Files/MySQL/MySQL Server 5.0/bin/mysqldump',
|
509 |
+
'/Program Files/MySQL/MySQL Server 4.1/bin/mysqldump'
|
510 |
+
);
|
511 |
+
|
512 |
+
// Find the one which works
|
513 |
+
foreach ( $mysqldump_locations as $location )
|
514 |
+
if ( is_executable( $this->conform_dir( $location ) ) )
|
515 |
+
$this->set_mysqldump_command_path( $location );
|
516 |
+
|
517 |
+
return $this->mysqldump_command_path;
|
518 |
+
|
519 |
+
}
|
520 |
+
|
521 |
+
/**
|
522 |
+
* Set the path to the mysqldump bin
|
523 |
+
*
|
524 |
+
* Setting the path to false will cause the database
|
525 |
+
* dump to use the php fallback
|
526 |
+
*
|
527 |
+
* @access public
|
528 |
+
* @param mixed $path
|
529 |
+
*/
|
530 |
+
public function set_mysqldump_command_path( $path ) {
|
531 |
+
|
532 |
+
$this->mysqldump_command_path = $path;
|
533 |
+
|
534 |
+
}
|
535 |
+
|
536 |
+
/**
|
537 |
+
* Get the path to the zip bin
|
538 |
+
*
|
539 |
+
* If not explicitly set will attempt to work
|
540 |
+
* it out by checking common locations
|
541 |
+
*
|
542 |
+
* @access public
|
543 |
+
* @return string
|
544 |
+
*/
|
545 |
+
public function get_zip_command_path() {
|
546 |
+
|
547 |
+
// Check shell_exec is available
|
548 |
+
if ( ! self::is_shell_exec_available() )
|
549 |
+
return '';
|
550 |
+
|
551 |
+
// Return now if it's already been set
|
552 |
+
if ( isset( $this->zip_command_path ) )
|
553 |
+
return $this->zip_command_path;
|
554 |
+
|
555 |
+
$this->zip_command_path = '';
|
556 |
+
|
557 |
+
// Does zip work
|
558 |
+
if ( is_null( shell_exec( 'hash zip 2>&1' ) ) ) {
|
559 |
+
|
560 |
+
// If so store it for later
|
561 |
+
$this->set_zip_command_path( 'zip' );
|
562 |
+
|
563 |
+
// And return now
|
564 |
+
return $this->zip_command_path;
|
565 |
+
|
566 |
+
}
|
567 |
+
|
568 |
+
// List of possible zip locations
|
569 |
+
$zip_locations = array(
|
570 |
+
'/usr/bin/zip'
|
571 |
+
);
|
572 |
+
|
573 |
+
// Find the one which works
|
574 |
+
foreach ( $zip_locations as $location )
|
575 |
+
if ( is_executable( $this->conform_dir( $location ) ) )
|
576 |
+
$this->set_zip_command_path( $location );
|
577 |
+
|
578 |
+
return $this->zip_command_path;
|
579 |
+
|
580 |
+
}
|
581 |
+
|
582 |
+
/**
|
583 |
+
* Set the path to the zip bin
|
584 |
+
*
|
585 |
+
* Setting the path to false will cause the database
|
586 |
+
* dump to use the php fallback
|
587 |
+
*
|
588 |
+
* @access public
|
589 |
+
* @param mixed $path
|
590 |
+
*/
|
591 |
+
public function set_zip_command_path( $path ) {
|
592 |
+
|
593 |
+
$this->zip_command_path = $path;
|
594 |
+
|
595 |
+
}
|
596 |
+
|
597 |
+
protected function do_action( $action ) {
|
598 |
+
|
599 |
+
do_action( $action, $this );
|
600 |
+
|
601 |
+
}
|
602 |
+
|
603 |
/**
|
604 |
* Kick off a backup
|
605 |
*
|
608 |
*/
|
609 |
public function backup() {
|
610 |
|
611 |
+
$this->do_action( 'hmbkp_backup_started' );
|
612 |
|
613 |
// Backup database
|
614 |
+
if ( $this->get_type() !== 'file' )
|
615 |
+
$this->dump_database();
|
616 |
|
617 |
// Zip everything up
|
618 |
$this->archive();
|
619 |
|
620 |
+
$this->do_action( 'hmbkp_backup_complete' );
|
621 |
|
622 |
}
|
623 |
|
628 |
* if not.
|
629 |
*
|
630 |
* @access public
|
|
|
631 |
*/
|
632 |
+
public function dump_database() {
|
633 |
|
634 |
+
$this->do_action( 'hmbkp_mysqldump_started' );
|
635 |
|
636 |
+
if ( $this->get_mysqldump_command_path() )
|
637 |
+
$this->mysqldump();
|
638 |
|
639 |
+
if ( empty( $this->mysqldump_verified ) )
|
640 |
+
$this->mysqldump_fallback();
|
641 |
|
642 |
+
$this->do_action( 'hmbkp_mysqldump_finished' );
|
|
|
643 |
|
644 |
+
}
|
|
|
645 |
|
646 |
+
public function mysqldump() {
|
|
|
647 |
|
648 |
+
$this->mysqldump_method = 'mysqldump';
|
|
|
649 |
|
650 |
+
$host = reset( explode( ':', DB_HOST ) );
|
651 |
+
$port = strpos( DB_HOST, ':' ) ? end( explode( ':', DB_HOST ) ) : '';
|
652 |
|
653 |
+
// Path to the mysqldump executable
|
654 |
+
$cmd = escapeshellarg( $this->get_mysqldump_command_path() );
|
|
|
655 |
|
656 |
+
// No Create DB command
|
657 |
+
$cmd .= ' --no-create-db';
|
658 |
|
659 |
+
// Make sure binary data is exported properly
|
660 |
+
$cmd .= ' --hex-blob';
|
|
|
661 |
|
662 |
+
// Username
|
663 |
+
$cmd .= ' -u ' . escapeshellarg( DB_USER );
|
664 |
|
665 |
+
// Don't pass the password if it's blank
|
666 |
+
if ( DB_PASSWORD )
|
667 |
+
$cmd .= ' -p' . escapeshellarg( DB_PASSWORD );
|
668 |
|
669 |
+
// Set the host
|
670 |
+
$cmd .= ' -h ' . escapeshellarg( $host );
|
671 |
|
672 |
+
// Set the port if it was set
|
673 |
+
if ( ! empty( $port ) )
|
674 |
+
$cmd .= ' -P ' . $port;
|
675 |
|
676 |
+
// The file we're saving too
|
677 |
+
$cmd .= ' -r ' . escapeshellarg( $this->get_database_dump_filepath() );
|
678 |
|
679 |
+
// The database we're dumping
|
680 |
+
$cmd .= ' ' . escapeshellarg( DB_NAME );
|
681 |
+
|
682 |
+
// Pipe STDERR to STDOUT
|
683 |
+
$cmd .= ' 2>&1';
|
684 |
|
685 |
+
// Store any returned data in warning
|
686 |
+
$this->warning( $this->get_mysqldump_method(), shell_exec( $cmd ) );
|
687 |
+
|
688 |
+
$this->verify_mysqldump();
|
689 |
|
690 |
}
|
691 |
|
693 |
* PHP mysqldump fallback functions, exports the database to a .sql file
|
694 |
*
|
695 |
* @access public
|
|
|
696 |
*/
|
697 |
public function mysqldump_fallback() {
|
698 |
|
699 |
+
$this->errors_to_warnings( $this->get_mysqldump_method() );
|
700 |
|
701 |
$this->mysqldump_method = 'mysqldump_fallback';
|
702 |
|
734 |
* Zip up all the files.
|
735 |
*
|
736 |
* Attempts to use the shell zip command, if
|
737 |
+
* thats not available then it falls back to
|
738 |
* PHP ZipArchive and finally PclZip.
|
739 |
*
|
740 |
* @access public
|
|
|
741 |
*/
|
742 |
public function archive() {
|
743 |
|
744 |
+
$this->do_action( 'hmbkp_archive_started' );
|
745 |
|
746 |
// Do we have the path to the zip command
|
747 |
+
if ( $this->get_zip_command_path() )
|
748 |
$this->zip();
|
749 |
|
750 |
// If not or if the shell zip failed then use ZipArchive
|
756 |
$this->pcl_zip();
|
757 |
|
758 |
// Delete the database dump file
|
759 |
+
if ( file_exists( $this->get_database_dump_filepath() ) )
|
760 |
+
unlink( $this->get_database_dump_filepath() );
|
761 |
|
762 |
+
$this->do_action( 'hmbkp_archive_finished' );
|
763 |
|
764 |
}
|
765 |
|
767 |
* Zip using the native zip command
|
768 |
*
|
769 |
* @access public
|
|
|
770 |
*/
|
771 |
public function zip() {
|
772 |
|
773 |
$this->archive_method = 'zip';
|
774 |
|
775 |
// Zip up $this->root with excludes
|
776 |
+
if ( $this->get_type() !== 'database' && $this->exclude_string( 'zip' ) )
|
777 |
+
$this->warning( $this->archive_method, shell_exec( 'cd ' . escapeshellarg( $this->get_root() ) . ' && ' . escapeshellarg( $this->get_zip_command_path() ) . ' -rq ' . escapeshellarg( $this->get_archive_filepath() ) . ' ./' . ' -x ' . $this->exclude_string( 'zip' ) . ' 2>&1' ) );
|
778 |
|
779 |
// Zip up $this->root without excludes
|
780 |
+
elseif ( $this->get_type() !== 'database' )
|
781 |
+
$this->warning( $this->archive_method, shell_exec( 'cd ' . escapeshellarg( $this->get_root() ) . ' && ' . escapeshellarg( $this->get_zip_command_path() ) . ' -rq ' . escapeshellarg( $this->get_archive_filepath() ) . ' ./' . ' 2>&1' ) );
|
782 |
|
783 |
// Add the database dump to the archive
|
784 |
+
if ( $this->get_type() !== 'file' )
|
785 |
+
$this->warning( $this->archive_method, shell_exec( 'cd ' . escapeshellarg( $this->get_path() ) . ' && ' . escapeshellarg( $this->get_zip_command_path() ) . ' -uq ' . escapeshellarg( $this->get_archive_filepath() ) . ' ' . escapeshellarg( $this->get_database_dump_filename() ) . ' 2>&1' ) );
|
786 |
|
787 |
+
$this->verify_archive();
|
788 |
|
789 |
}
|
790 |
|
791 |
/**
|
792 |
* Fallback for creating zip archives if zip command is
|
793 |
+
* unavailable.
|
794 |
*
|
795 |
* @access public
|
796 |
* @param string $path
|
802 |
|
803 |
$zip = new ZipArchive();
|
804 |
|
805 |
+
if ( ! class_exists( 'ZipArchive' ) || ! $zip->open( $this->get_archive_filepath(), ZIPARCHIVE::CREATE ) )
|
806 |
return;
|
807 |
|
808 |
+
$excludes = $this->exclude_string( 'regex' );
|
809 |
+
|
810 |
+
if ( $this->get_type() !== 'database' ) {
|
811 |
|
812 |
$files_added = 0;
|
813 |
|
814 |
+
foreach ( $this->get_files() as $file ) {
|
815 |
+
|
816 |
+
if ( $file === '.' || $file === '..' || ! $file->isReadable() )
|
817 |
+
continue;
|
818 |
+
|
819 |
+
// Excludes
|
820 |
+
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', $this->conform_dir( $file->getPathname() ) ) ) )
|
821 |
+
continue;
|
822 |
|
823 |
+
if ( $file->isDir() )
|
824 |
+
$zip->addEmptyDir( trailingslashit( str_ireplace( trailingslashit( $this->get_root() ), '', $this->conform_dir( $file->getPathname() ) ) ) );
|
825 |
|
826 |
+
elseif ( $file->isFile() )
|
827 |
+
$zip->addFile( $file->getPathname(), str_ireplace( trailingslashit( $this->get_root() ), '', $this->conform_dir( $file->getPathname() ) ) );
|
828 |
|
829 |
if ( ++$files_added % 500 === 0 )
|
830 |
+
if ( ! $zip->close() || ! $zip->open( $this->get_archive_filepath(), ZIPARCHIVE::CREATE ) )
|
831 |
return;
|
832 |
|
833 |
}
|
835 |
}
|
836 |
|
837 |
// Add the database
|
838 |
+
if ( $this->get_type() !== 'file' )
|
839 |
+
$zip->addFile( $this->get_database_dump_filepath(), $this->get_database_dump_filename() );
|
840 |
|
841 |
if ( $zip->status )
|
842 |
$this->warning( $this->archive_method, $zip->status );
|
846 |
|
847 |
$zip->close();
|
848 |
|
849 |
+
$this->verify_archive();
|
850 |
|
851 |
}
|
852 |
|
853 |
/**
|
854 |
* Fallback for creating zip archives if zip command and ZipArchive are
|
855 |
+
* unavailable.
|
856 |
*
|
857 |
* Uses the PclZip library that ships with WordPress
|
858 |
*
|
870 |
|
871 |
$this->load_pclzip();
|
872 |
|
873 |
+
$archive = new PclZip( $this->get_archive_filepath() );
|
874 |
|
875 |
// Zip up everything
|
876 |
+
if ( $this->get_type() !== 'database' )
|
877 |
+
if ( ! $archive->add( $this->get_root(), PCLZIP_OPT_REMOVE_PATH, $this->get_root(), PCLZIP_CB_PRE_ADD, 'hmbkp_pclzip_callback' ) )
|
878 |
$this->warning( $this->archive_method, $archive->errorInfo( true ) );
|
879 |
|
880 |
// Add the database
|
881 |
+
if ( $this->get_type() !== 'file' )
|
882 |
+
if ( ! $archive->add( $this->get_database_dump_filepath(), PCLZIP_OPT_REMOVE_PATH, $this->get_path() ) )
|
883 |
$this->warning( $this->archive_method, $archive->errorInfo( true ) );
|
884 |
|
885 |
unset( $GLOBALS['_hmbkp_exclude_string'] );
|
886 |
|
887 |
+
$this->verify_archive();
|
888 |
+
|
889 |
+
}
|
890 |
+
|
891 |
+
public function verify_mysqldump() {
|
892 |
+
|
893 |
+
// If we've already passed then no need to check again
|
894 |
+
if ( ! empty( $this->mysqldump_verified ) )
|
895 |
+
return true;
|
896 |
+
|
897 |
+
if ( ! file_exists( $this->get_database_dump_filepath() ) )
|
898 |
+
$this->error( $this->get_mysqldump_method(), __( 'The mysqldump file was not created', 'hmbkp' ) );
|
899 |
+
|
900 |
+
if ( $this->get_errors( $this->get_mysqldump_method() ) )
|
901 |
+
return false;
|
902 |
+
|
903 |
+
return $this->mysqldump_verified = true;
|
904 |
+
|
905 |
|
906 |
}
|
907 |
|
911 |
* @access public
|
912 |
* @return bool
|
913 |
*/
|
914 |
+
public function verify_archive() {
|
915 |
|
916 |
// If we've already passed then no need to check again
|
917 |
if ( ! empty( $this->archive_verified ) )
|
918 |
return true;
|
919 |
|
920 |
+
if ( ! file_exists( $this->get_archive_filepath() ) )
|
921 |
+
$this->error( $this->get_archive_method(), __( 'The backup file was not created', 'hmbkp' ) );
|
922 |
|
923 |
// Verify using the zip command if possible
|
924 |
+
if ( $this->get_zip_command_path() && $this->get_archive_method() === 'zip' ) {
|
925 |
|
926 |
+
$verify = shell_exec( escapeshellarg( $this->get_zip_command_path() ) . ' -T ' . escapeshellarg( $this->get_archive_filepath() ) . ' 2> /dev/null' );
|
927 |
|
928 |
if ( strpos( $verify, 'OK' ) === false )
|
929 |
+
$this->error( $this->get_archive_method(), $verify );
|
930 |
|
931 |
}
|
932 |
|
933 |
// If there are errors delete the backup file.
|
934 |
+
if ( $this->get_errors( $this->get_archive_method() ) && file_exists( $this->get_archive_filepath() ) )
|
935 |
+
unlink( $this->get_archive_filepath() );
|
936 |
|
937 |
+
if ( $this->get_errors( $this->get_archive_method() ) )
|
938 |
return false;
|
939 |
|
940 |
+
if ( $this->get_unreadable_files() )
|
941 |
+
$this->warning( $this->get_archive_method(), __( 'The following files are unreadable and couldn\'t be backed up: ', 'hmbkp' ) . implode( ', ', $this->get_unreadable_files() ) );
|
942 |
+
|
943 |
return $this->archive_verified = true;
|
944 |
|
945 |
}
|
946 |
|
947 |
/**
|
948 |
+
* Return an array of all files in the filesystem
|
|
|
949 |
*
|
950 |
* @access public
|
951 |
* @return array
|
952 |
*/
|
953 |
+
public function get_files() {
|
954 |
|
955 |
if ( ! empty( $this->files ) )
|
956 |
return $this->files;
|
957 |
|
958 |
$this->files = array();
|
959 |
|
960 |
+
if ( defined( 'RecursiveDirectoryIterator::FOLLOW_SYMLINKS' ) )
|
961 |
+
$this->files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $this->get_root(), RecursiveDirectoryIterator::FOLLOW_SYMLINKS ), RecursiveIteratorIterator::SELF_FIRST, RecursiveIteratorIterator::CATCH_GET_CHILD );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
962 |
|
963 |
+
else
|
964 |
+
$this->files = $this->get_files_fallback( $this->get_root() );
|
|
|
|
|
|
|
|
|
965 |
|
966 |
return $this->files;
|
967 |
|
974 |
* Used if RecursiveDirectoryIterator::FOLLOW_SYMLINKS isn't available
|
975 |
*
|
976 |
* @access private
|
977 |
+
* @param string $dir
|
978 |
* @param array $files. (default: array())
|
979 |
* @return array
|
980 |
*/
|
981 |
+
private function get_files_fallback( $dir, $files = array() ) {
|
982 |
|
983 |
$handle = opendir( $dir );
|
984 |
|
987 |
while ( $file = readdir( $handle ) ) :
|
988 |
|
989 |
// Ignore current dir and containing dir and any unreadable files or directories
|
990 |
+
if ( $file === '.' || $file === '..' )
|
991 |
continue;
|
992 |
|
993 |
$filepath = $this->conform_dir( trailingslashit( $dir ) . $file );
|
994 |
+
$file = str_ireplace( trailingslashit( $this->get_root() ), '', $filepath );
|
995 |
|
996 |
+
$files[] = new SplFileInfo( $filepath );
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
997 |
|
998 |
if ( is_dir( $filepath ) )
|
999 |
+
$files = $this->get_files_fallback( $filepath, $files );
|
1000 |
|
1001 |
endwhile;
|
1002 |
|
1004 |
|
1005 |
}
|
1006 |
|
1007 |
+
/**
|
1008 |
+
* Returns an array of files that will be included in the backup.
|
1009 |
+
*
|
1010 |
+
* @access public
|
1011 |
+
* @return array
|
1012 |
+
*/
|
1013 |
+
public function get_included_files() {
|
1014 |
+
|
1015 |
+
if ( ! empty( $this->included_files ) )
|
1016 |
+
return $this->included_files;
|
1017 |
+
|
1018 |
+
$this->included_files = array();
|
1019 |
+
|
1020 |
+
$excludes = $this->exclude_string( 'regex' );
|
1021 |
+
|
1022 |
+
foreach ( $this->get_files() as $file ) {
|
1023 |
+
|
1024 |
+
if ( $file === '.' || $file === '..' || ! $file->isReadable() )
|
1025 |
+
continue;
|
1026 |
+
|
1027 |
+
// Excludes
|
1028 |
+
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', $this->conform_dir( $file->getPathname() ) ) ) )
|
1029 |
+
continue;
|
1030 |
+
|
1031 |
+
$this->included_files[] = $file;
|
1032 |
+
|
1033 |
+
}
|
1034 |
+
|
1035 |
+
return $this->included_files;
|
1036 |
+
|
1037 |
+
}
|
1038 |
+
|
1039 |
+
/**
|
1040 |
+
* Returns an array of files that match the exclude rules.
|
1041 |
+
*
|
1042 |
+
* @access public
|
1043 |
+
* @return array
|
1044 |
+
*/
|
1045 |
+
public function get_excluded_files() {
|
1046 |
+
|
1047 |
+
if ( ! empty( $this->excluded_files ) )
|
1048 |
+
return $this->excluded_files;
|
1049 |
+
|
1050 |
+
$this->excluded_files = array();
|
1051 |
+
|
1052 |
+
$excludes = $this->exclude_string( 'regex' );
|
1053 |
+
|
1054 |
+
foreach ( $this->get_files() as $file ) {
|
1055 |
+
|
1056 |
+
if ( $file === '.' || $file === '..' || ! $file->isReadable() )
|
1057 |
+
continue;
|
1058 |
+
|
1059 |
+
// Excludes
|
1060 |
+
if ( $excludes && preg_match( '(' . $excludes . ')', str_ireplace( trailingslashit( $this->get_root() ), '', $this->conform_dir( $file->getPathname() ) ) ) )
|
1061 |
+
$this->excluded_files[] = $file;
|
1062 |
+
|
1063 |
+
}
|
1064 |
+
|
1065 |
+
return $this->excluded_files;
|
1066 |
+
|
1067 |
+
}
|
1068 |
+
|
1069 |
+
/**
|
1070 |
+
* Returns an array of unreadable files.
|
1071 |
+
*
|
1072 |
+
* @access public
|
1073 |
+
* @return array
|
1074 |
+
*/
|
1075 |
+
public function get_unreadable_files() {
|
1076 |
+
|
1077 |
+
if ( ! empty( $this->unreadable_files ) )
|
1078 |
+
return $this->unreadable_files;
|
1079 |
+
|
1080 |
+
$this->unreadable_files = array();
|
1081 |
+
|
1082 |
+
foreach ( $this->get_files() as $file ) {
|
1083 |
+
|
1084 |
+
if ( $file === '.' || $file === '..' )
|
1085 |
+
continue;
|
1086 |
+
|
1087 |
+
if ( ! $file->isReadable() )
|
1088 |
+
$this->unreadable_files[] = $file;
|
1089 |
+
|
1090 |
+
}
|
1091 |
+
|
1092 |
+
return $this->unreadable_files;
|
1093 |
+
|
1094 |
+
}
|
1095 |
+
|
1096 |
private function load_pclzip() {
|
1097 |
|
1098 |
// Load PclZip
|
1099 |
if ( ! defined( 'PCLZIP_TEMPORARY_DIR' ) )
|
1100 |
+
define( 'PCLZIP_TEMPORARY_DIR', trailingslashit( $this->get_path() ) );
|
1101 |
|
1102 |
require_once( ABSPATH . 'wp-admin/includes/class-pclzip.php' );
|
1103 |
|
1104 |
}
|
1105 |
|
1106 |
/**
|
1107 |
+
* Get an array of exclude rules
|
1108 |
+
*
|
1109 |
+
* The backup path is automatically excluded
|
1110 |
*
|
1111 |
* @access public
|
1112 |
+
* @return array
|
1113 |
*/
|
1114 |
+
public function get_excludes() {
|
|
|
|
|
|
|
1115 |
|
1116 |
+
$excludes = array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1117 |
|
1118 |
+
if ( isset( $this->excludes ) )
|
1119 |
+
$excludes = $this->excludes;
|
1120 |
|
1121 |
+
// If path() is inside root(), exclude it
|
1122 |
+
if ( strpos( $this->get_path(), $this->get_root() ) !== false )
|
1123 |
+
array_unshift( $excludes, trailingslashit( $this->get_path() ) );
|
|
|
1124 |
|
1125 |
+
return array_unique( $excludes );
|
1126 |
|
1127 |
}
|
1128 |
|
1129 |
/**
|
1130 |
+
* Set the excludes, expects and array
|
1131 |
*
|
1132 |
* @access public
|
1133 |
+
* @param Array $excludes
|
1134 |
+
* @param Bool $append
|
1135 |
*/
|
1136 |
+
public function set_excludes( $excludes, $append = false ) {
|
1137 |
|
1138 |
+
if ( is_string( $excludes ) )
|
1139 |
+
$excludes = explode( ',', $excludes );
|
|
|
|
|
|
|
|
|
|
|
|
|
1140 |
|
1141 |
+
if ( $append )
|
1142 |
+
$excludes = array_merge( $this->excludes, $excludes );
|
1143 |
|
1144 |
+
$this->excludes = array_filter( array_unique( array_map( 'trim', $excludes ) ) );
|
|
|
|
|
|
|
|
|
|
|
1145 |
|
1146 |
}
|
1147 |
|
1155 |
* @param string $context. (default: 'zip')
|
1156 |
* @return string
|
1157 |
*/
|
1158 |
+
protected function exclude_string( $context = 'zip' ) {
|
1159 |
|
1160 |
// Return a comma separated list by default
|
1161 |
$separator = ', ';
|
1162 |
$wildcard = '';
|
1163 |
|
1164 |
// The zip command
|
1165 |
+
if ( $context === 'zip' ) {
|
1166 |
$wildcard = '*';
|
1167 |
$separator = ' -x ';
|
1168 |
|
1169 |
// The PclZip fallback library
|
1170 |
+
} elseif ( $context === 'regex' ) {
|
1171 |
$wildcard = '([\s\S]*?)';
|
1172 |
$separator = '|';
|
1173 |
|
1174 |
}
|
1175 |
|
1176 |
+
$excludes = $this->get_excludes();
|
|
|
|
|
|
|
|
|
|
|
1177 |
|
1178 |
foreach( $excludes as $key => &$rule ) {
|
1179 |
|
1192 |
$fragment = true;
|
1193 |
|
1194 |
// Strip $this->root and conform
|
1195 |
+
$rule = str_ireplace( $this->get_root(), '', untrailingslashit( $this->conform_dir( $rule ) ) );
|
1196 |
|
1197 |
// Strip the preceeding slash
|
1198 |
if ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) )
|
1199 |
$rule = substr( $rule, 1 );
|
1200 |
|
1201 |
// Escape string for regex
|
1202 |
+
if ( $context === 'regex' )
|
1203 |
$rule = str_replace( '.', '\.', $rule );
|
1204 |
|
1205 |
// Convert any existing wildcards
|
1206 |
+
if ( $wildcard !== '*' && strpos( $rule, '*' ) !== false )
|
1207 |
$rule = str_replace( '*', $wildcard, $rule );
|
1208 |
|
1209 |
// Wrap directory fragments and files in wildcards for zip
|
1210 |
+
if ( $context === 'zip' && ( $fragment || $file ) )
|
1211 |
$rule = $wildcard . $rule . $wildcard;
|
1212 |
|
1213 |
// Add a wildcard to the end of absolute url for zips
|
1214 |
+
if ( $context === 'zip' && $absolute )
|
1215 |
$rule .= $wildcard;
|
1216 |
|
1217 |
// Add and end carrot to files for pclzip but only if it doesn't end in a wildcard
|
1218 |
+
if ( $file && $context === 'regex' )
|
1219 |
$rule .= '$';
|
1220 |
|
1221 |
// Add a start carrot to absolute urls for pclzip
|
1222 |
+
if ( $absolute && $context === 'regex' )
|
1223 |
$rule = '^' . $rule;
|
1224 |
|
1225 |
}
|
1226 |
|
1227 |
// Escape shell args for zip command
|
1228 |
+
if ( $context === 'zip' )
|
1229 |
$excludes = array_map( 'escapeshellarg', array_unique( $excludes ) );
|
1230 |
|
1231 |
return implode( $separator, $excludes );
|
1233 |
}
|
1234 |
|
1235 |
/**
|
1236 |
+
* Add backquotes to tables and db-names in SQL queries. Taken from phpMyAdmin.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1237 |
*
|
1238 |
* @access private
|
1239 |
* @param mixed $a_name
|
1240 |
*/
|
1241 |
private function sql_backquote( $a_name ) {
|
1242 |
|
1243 |
+
if ( ! empty( $a_name ) && $a_name !== '*' ) {
|
1244 |
|
1245 |
if ( is_array( $a_name ) ) {
|
1246 |
|
1339 |
$field_set[$j] = $this->sql_backquote( mysql_field_name( $result, $j ) );
|
1340 |
$type = mysql_field_type( $result, $j );
|
1341 |
|
1342 |
+
if ( $type === 'tinyint' || $type === 'smallint' || $type === 'mediumint' || $type === 'int' || $type === 'bigint' || $type === 'timestamp')
|
1343 |
$field_num[$j] = true;
|
1344 |
|
1345 |
else
|
1364 |
if ( ! isset($row[$j] ) ) {
|
1365 |
$values[] = 'NULL';
|
1366 |
|
1367 |
+
} elseif ( $row[$j] === '0' || $row[$j] !== '' ) {
|
1368 |
|
1369 |
// a number
|
1370 |
if ( $field_num[$j] )
|
1383 |
$sql_file .= " \n" . $entries . implode( ', ', $values ) . ") ;";
|
1384 |
|
1385 |
// write the rows in batches of 100
|
1386 |
+
if ( $batch_write === 100 ) {
|
1387 |
$batch_write = 0;
|
1388 |
$this->write_sql( $sql_file );
|
1389 |
$sql_file = '';
|
1437 |
*/
|
1438 |
private function write_sql( $sql ) {
|
1439 |
|
1440 |
+
$sqlname = $this->get_database_dump_filepath();
|
1441 |
|
1442 |
// Actually write the sql file
|
1443 |
if ( is_writable( $sqlname ) || ! file_exists( $sqlname ) ) {
|
1444 |
|
1445 |
+
if ( ! $handle = @fopen( $sqlname, 'a' ) )
|
1446 |
return;
|
1447 |
|
1448 |
if ( ! fwrite( $handle, $sql ) )
|
1460 |
* Get the errors
|
1461 |
*
|
1462 |
* @access public
|
|
|
1463 |
*/
|
1464 |
+
public function get_errors( $context = null ) {
|
1465 |
|
1466 |
if ( ! empty( $context ) )
|
1467 |
return isset( $this->errors[$context] ) ? $this->errors[$context] : array();
|
1470 |
|
1471 |
}
|
1472 |
|
|
|
1473 |
/**
|
1474 |
* Add an error to the errors stack
|
1475 |
*
|
1476 |
* @access private
|
1477 |
* @param string $context
|
1478 |
* @param mixed $error
|
|
|
1479 |
*/
|
1480 |
private function error( $context, $error ) {
|
1481 |
|
1491 |
*
|
1492 |
* @access private
|
1493 |
* @param string $context. (default: null)
|
|
|
1494 |
*/
|
1495 |
private function errors_to_warnings( $context = null ) {
|
1496 |
|
1497 |
+
$errors = empty( $context ) ? $this->get_errors() : array( $context => $this->get_errors( $context ) );
|
1498 |
|
1499 |
if ( empty( $errors ) )
|
1500 |
return;
|
1515 |
* Get the warnings
|
1516 |
*
|
1517 |
* @access public
|
|
|
1518 |
*/
|
1519 |
+
public function get_warnings( $context = null ) {
|
1520 |
|
1521 |
if ( ! empty( $context ) )
|
1522 |
return isset( $this->warnings[$context] ) ? $this->warnings[$context] : array();
|
1525 |
|
1526 |
}
|
1527 |
|
|
|
1528 |
/**
|
1529 |
* Add an warning to the warnings stack
|
1530 |
*
|
1531 |
* @access private
|
1532 |
* @param string $context
|
1533 |
* @param mixed $warning
|
|
|
1534 |
*/
|
1535 |
private function warning( $context, $warning ) {
|
1536 |
|
1541 |
|
1542 |
}
|
1543 |
|
|
|
1544 |
/**
|
1545 |
* Custom error handler for catching errors
|
1546 |
*
|
1549 |
* @param string $message
|
1550 |
* @param string $file
|
1551 |
* @param string $line
|
|
|
1552 |
*/
|
1553 |
public function error_handler( $type ) {
|
1554 |
|
1555 |
+
if ( ( defined( 'E_DEPRECATED' ) && $type === E_DEPRECATED ) || ( defined( 'E_STRICT' ) && $type === E_STRICT ) || error_reporting() === 0 )
|
1556 |
return false;
|
1557 |
|
1558 |
$args = func_get_args();
|
languages/hmbkp-de_DE.mo
CHANGED
Binary file
|
languages/hmbkp-de_DE.po
CHANGED
@@ -2,8 +2,8 @@ msgid ""
|
|
2 |
msgstr ""
|
3 |
"Project-Id-Version: BackUpWordPress\n"
|
4 |
"Report-Msgid-Bugs-To: \n"
|
5 |
-
"POT-Creation-Date: 2012-08-
|
6 |
-
"PO-Revision-Date: 2012-08-
|
7 |
"Last-Translator: Flo Edelmann <florian-edelmann@online.de>\n"
|
8 |
"Language-Team: Flo Edelmann <florian-edelmann@online.de>\n"
|
9 |
"Language: \n"
|
@@ -18,522 +18,737 @@ msgstr ""
|
|
18 |
"X-Poedit-SourceCharset: utf-8\n"
|
19 |
"X-Poedit-SearchPath-0: .\n"
|
20 |
|
21 |
-
#:
|
22 |
-
|
23 |
-
|
24 |
-
msgstr "Einstellungen"
|
25 |
|
26 |
-
#:
|
27 |
#, php-format
|
28 |
-
msgid "
|
29 |
-
msgstr "
|
30 |
-
|
31 |
-
#: admin.settings.php:5
|
32 |
-
#: admin.constants.php:3
|
33 |
-
#: admin.menus.php:76
|
34 |
-
msgid "Constants"
|
35 |
-
msgstr "Konstanten"
|
36 |
-
|
37 |
-
#: admin.settings.php:5
|
38 |
-
msgid "help panel"
|
39 |
-
msgstr "Hilfe-Panel"
|
40 |
-
|
41 |
-
#: admin.settings.php:16
|
42 |
-
msgid "Automatic Backups"
|
43 |
-
msgstr "Automatische Backups"
|
44 |
-
|
45 |
-
#: admin.settings.php:22
|
46 |
-
msgid "Backup my site automatically."
|
47 |
-
msgstr "Sichere meine Seite automatisch."
|
48 |
-
|
49 |
-
#: admin.settings.php:27
|
50 |
-
msgid "No automatic backups."
|
51 |
-
msgstr "Keine automatischen Backups."
|
52 |
-
|
53 |
-
#: admin.settings.php:36
|
54 |
-
msgid "Frequency of backups"
|
55 |
-
msgstr "Häufigkeit der Backups"
|
56 |
-
|
57 |
-
#: admin.settings.php:40
|
58 |
-
msgid "Automatic backups will occur"
|
59 |
-
msgstr "Automatische Backups werden ausgeführt:"
|
60 |
-
|
61 |
-
#: admin.settings.php:43
|
62 |
-
msgid "Daily"
|
63 |
-
msgstr "Täglich"
|
64 |
-
|
65 |
-
#: admin.settings.php:44
|
66 |
-
msgid "Weekly"
|
67 |
-
msgstr "Wöchentlich"
|
68 |
-
|
69 |
-
#: admin.settings.php:45
|
70 |
-
msgid "Fortnightly"
|
71 |
-
msgstr "Vierzehntägig"
|
72 |
|
73 |
-
#:
|
74 |
-
|
75 |
-
|
|
|
76 |
|
77 |
-
#:
|
78 |
-
msgid "
|
79 |
-
msgstr "
|
80 |
|
81 |
-
#:
|
82 |
-
msgid "
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
msgid "database only"
|
91 |
-
msgstr "Datenbank"
|
92 |
-
|
93 |
-
#: admin.settings.php:64
|
94 |
-
msgid "files only"
|
95 |
-
msgstr "Dateien"
|
96 |
|
97 |
-
#:
|
98 |
-
msgid "
|
99 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
100 |
|
101 |
-
#:
|
102 |
-
|
103 |
-
|
104 |
-
|
|
|
|
|
|
|
|
|
|
|
105 |
|
106 |
-
#:
|
107 |
-
msgid "
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
-
#:
|
111 |
-
msgid "
|
112 |
-
msgstr "
|
113 |
|
114 |
-
#:
|
115 |
-
msgid "
|
116 |
-
msgstr "
|
117 |
|
118 |
-
#:
|
119 |
-
msgid "
|
120 |
-
msgstr "
|
121 |
-
|
122 |
-
#: admin.settings.php:86
|
123 |
-
#: admin.constants.php:8
|
124 |
-
#: admin.constants.php:11
|
125 |
-
#: admin.constants.php:14
|
126 |
-
#: admin.constants.php:17
|
127 |
-
#: admin.constants.php:20
|
128 |
-
#: admin.constants.php:23
|
129 |
-
#: admin.constants.php:26
|
130 |
-
#: admin.constants.php:29
|
131 |
-
#: admin.constants.php:32
|
132 |
-
#: admin.constants.php:35
|
133 |
-
#: admin.constants.php:38
|
134 |
-
#: admin.constants.php:41
|
135 |
-
msgid "e.g."
|
136 |
-
msgstr "z.B."
|
137 |
|
138 |
-
#:
|
139 |
-
msgid "
|
140 |
-
msgstr "
|
141 |
|
142 |
-
#:
|
143 |
#, php-format
|
144 |
-
msgid "
|
145 |
-
|
146 |
-
msgstr[0] "1 Backup fertiggestellt"
|
147 |
-
msgstr[1] "%d Backups fertiggestellt"
|
148 |
-
|
149 |
-
#: admin.backups-table.php:13
|
150 |
-
msgid "Size"
|
151 |
-
msgstr "Größe"
|
152 |
-
|
153 |
-
#: admin.backups-table.php:14
|
154 |
-
msgid "Actions"
|
155 |
-
msgstr "Aktionen"
|
156 |
|
157 |
-
#:
|
158 |
#, php-format
|
159 |
-
msgid "
|
160 |
-
|
161 |
-
msgstr[0] "Nur das neueste Backup wird gespeichert"
|
162 |
-
msgstr[1] "Die %d neuesten Backups werden gespeichert"
|
163 |
|
164 |
-
#:
|
165 |
#, php-format
|
166 |
-
msgid "
|
167 |
-
msgstr "
|
168 |
-
|
169 |
-
#: admin.page.php:7
|
170 |
-
#: admin.menus.php:10
|
171 |
-
msgid "Manage Backups"
|
172 |
-
msgstr "Backups verwalten"
|
173 |
|
174 |
-
#:
|
175 |
-
msgid "You need to fix the issues detailed above before BackUpWordPress can start."
|
176 |
-
msgstr "Du musst die Probleme, die oben beschrieben werden, beheben, bevor BackUpWordPress starten kann."
|
177 |
-
|
178 |
-
#: admin.page.php:29
|
179 |
#, php-format
|
180 |
-
msgid "
|
181 |
-
msgstr "
|
182 |
|
183 |
-
#:
|
184 |
-
msgid "
|
185 |
-
msgstr "
|
186 |
|
187 |
-
#:
|
188 |
-
msgid "
|
189 |
-
msgstr "
|
190 |
|
191 |
-
#: admin
|
192 |
#, php-format
|
193 |
msgid "You can %1$s any of the following %2$s in your %3$s to control advanced settings. %4$s. Defined %5$s will be highlighted."
|
194 |
msgstr "Du kannst jede der folgenden %2$s in deinem %3$s %1$sn, um erweiterte Einstellungen vorzunehmen. %4$s. Definierte %5$s werden hervorgehoben."
|
195 |
|
196 |
-
#: admin
|
|
|
|
|
|
|
|
|
197 |
msgid "The Codex can help"
|
198 |
msgstr "Der Codex kann helfen"
|
199 |
|
200 |
-
#: admin
|
201 |
#, php-format
|
202 |
msgid "The path to folder you would like to store your backup files in, defaults to %s."
|
203 |
msgstr "Der Pfad zum Verzeichnis, in dem du die Backups speichern möchtest. Standard: %s"
|
204 |
|
205 |
-
#: admin
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
206 |
#, php-format
|
207 |
msgid "The path to your %1$s executable. Will be used for the %2$s part of the back up if available."
|
208 |
msgstr "Der Pfad zur ausführbaren %1$s-Datei. Wird für den %2$s-Teil des Backups genutzt, wenn verfügbar."
|
209 |
|
210 |
-
#: admin
|
211 |
-
#: admin
|
212 |
-
#: admin
|
213 |
-
#: admin
|
214 |
-
#: admin.status.php:14
|
215 |
-
#: admin.status.php:18
|
216 |
msgid "database"
|
217 |
msgstr "Datenbank"
|
218 |
|
219 |
-
#: admin
|
220 |
#, php-format
|
221 |
msgid "The path to your %1$s executable. Will be used to zip up your %2$s and %3$s if available."
|
222 |
msgstr "Der Pfad zur ausführbaren %1$s-Datei. Wird genutzt, um deine %2$s und %3$s als ZIP-Archiv zu komprimieren, wenn verfügbar."
|
223 |
|
224 |
-
#: admin
|
225 |
-
#: admin
|
226 |
-
#: admin
|
227 |
-
#: admin.status.php:14
|
228 |
-
#: admin.status.php:22
|
229 |
msgid "files"
|
230 |
msgstr "Dateien"
|
231 |
|
232 |
-
#: admin
|
233 |
#, php-format
|
234 |
msgid "Completely disables the automatic back up. You can still back up using the \"Back Up Now\" button. Defaults to %s."
|
235 |
msgstr "Deaktiviert die automatischen Backups vollständig. Du kannst trotzdem Backups erstellen, indem du den \"Jetzt sichern\"-Button verwendest. Standard: %s"
|
236 |
|
237 |
-
#: admin
|
238 |
#, php-format
|
239 |
msgid "Number of backups to keep, older backups will be deleted automatically when a new backup is completed. Defaults to %s."
|
240 |
msgstr "Anzahl der zu behaltenden Backups. Ältere Backups werden automatisch gelöscht, sobald ein neues Backup fertiggestellt ist. Standard: %s"
|
241 |
|
242 |
-
#: admin
|
243 |
-
#: admin
|
244 |
#, php-format
|
245 |
msgid "Backup %1$s only, your %2$s won't be backed up. Defaults to %3$s."
|
246 |
msgstr "Nur die %1$s sichern, deine %2$s werden nicht gesichert. Standard: %3$s"
|
247 |
|
248 |
-
#: admin
|
249 |
#, php-format
|
250 |
msgid "The time that the daily back up should run. Defaults to %s."
|
251 |
msgstr "Die Zeit, zu der das tägliche Backup laufen soll. Standard: %s"
|
252 |
|
253 |
-
#: admin
|
254 |
#, php-format
|
255 |
msgid "Attempt to email a copy of your backups. Value should be email address to send backups to. Defaults to %s."
|
256 |
msgstr "Versuche, eine Kopie des Backups per E-Mail zu senden. Der Wert sollte eine E-Mail-Adresse sein. Standard: %s"
|
257 |
|
258 |
-
#: admin
|
259 |
msgid "Comma separated list of files or directories to exclude, the backups directory is automatically excluded."
|
260 |
msgstr "Kommagetrennte Liste von Dateien oder Verzeichnissen, die ausgeschlossen werden sollen (das Backup-Verzeichnis ist automatisch ausgeschlossen)."
|
261 |
|
262 |
-
#: admin
|
263 |
#, php-format
|
264 |
msgid "The capability to use when calling %1$s. Defaults to %2$s."
|
265 |
msgstr "Die Rolle, die beim Aufrufen von %1$s benutzt wird. Standard: %2$s"
|
266 |
|
267 |
-
#: admin
|
268 |
#, php-format
|
269 |
msgid "The root directory that is backed up. Defaults to %s."
|
270 |
msgstr "Das Wurzelverzeichnis, das gesichert wird. Standard: %s"
|
271 |
|
272 |
-
#: admin.
|
273 |
-
msgid "
|
274 |
-
msgstr "
|
|
|
|
|
|
|
|
|
275 |
|
276 |
-
#: admin.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
277 |
#, php-format
|
278 |
-
msgid "%s
|
279 |
-
msgstr "
|
280 |
|
281 |
-
#: admin.
|
282 |
-
|
283 |
-
|
284 |
-
|
285 |
-
#: functions/interface.functions.php:120
|
286 |
-
#: functions/interface.functions.php:130
|
287 |
-
#: functions/interface.functions.php:140
|
288 |
-
#: functions/interface.functions.php:150
|
289 |
-
msgid "BackUpWordPress has detected a problem."
|
290 |
-
msgstr "BackUpWordPress hat ein Problem entdeckt."
|
291 |
|
292 |
-
#: admin.
|
293 |
#, php-format
|
294 |
-
msgid "
|
295 |
-
msgstr "
|
296 |
|
297 |
-
#: admin.
|
298 |
-
|
299 |
-
msgid "
|
300 |
-
msgstr "
|
301 |
|
302 |
-
#: admin.
|
303 |
-
|
304 |
-
|
|
|
305 |
|
306 |
-
#: admin.
|
307 |
#, php-format
|
308 |
-
msgid "
|
309 |
-
msgstr "
|
310 |
|
311 |
-
#: admin.
|
312 |
-
msgid "
|
313 |
-
msgstr "
|
314 |
|
315 |
-
#: admin.
|
316 |
-
|
317 |
-
|
|
|
318 |
|
319 |
-
#: admin.
|
320 |
-
|
321 |
-
|
|
|
322 |
|
323 |
-
#: admin.
|
324 |
-
|
325 |
-
|
|
|
326 |
|
327 |
-
#:
|
328 |
-
|
329 |
-
|
|
|
|
|
|
|
|
|
|
|
330 |
|
331 |
-
#:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
332 |
#, php-format
|
333 |
-
msgid "
|
334 |
-
msgstr "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
335 |
|
336 |
-
#: admin.
|
337 |
#, php-format
|
338 |
-
msgid "
|
339 |
-
msgstr "
|
340 |
|
341 |
-
#: admin.
|
342 |
-
msgid "
|
343 |
-
msgstr "
|
344 |
|
345 |
-
#: admin.
|
346 |
-
msgid "
|
347 |
-
msgstr "
|
348 |
|
349 |
-
#: admin.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
350 |
#, php-format
|
351 |
-
msgid "
|
352 |
-
msgid_plural "
|
353 |
-
msgstr[0] "
|
354 |
-
msgstr[1] "
|
355 |
|
356 |
-
#: admin.
|
357 |
#, php-format
|
358 |
-
msgid "
|
359 |
-
msgstr "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
360 |
|
361 |
-
#: admin.
|
362 |
#, php-format
|
363 |
-
msgid "
|
364 |
-
msgstr "
|
365 |
|
366 |
-
#: admin.
|
367 |
-
msgid "
|
368 |
-
msgstr "
|
369 |
|
370 |
-
#: admin.
|
371 |
#, php-format
|
372 |
-
msgid "
|
373 |
-
|
|
|
|
|
374 |
|
375 |
-
#: admin.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
376 |
#, php-format
|
377 |
-
msgid "The
|
378 |
-
msgstr "
|
379 |
|
380 |
-
#:
|
381 |
-
msgid "
|
382 |
-
msgstr "
|
383 |
|
384 |
-
#:
|
385 |
-
msgid "
|
386 |
-
msgstr "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
387 |
|
388 |
-
#: functions/
|
|
|
|
|
|
|
|
|
|
|
389 |
msgid "Download"
|
390 |
msgstr "Download"
|
391 |
|
392 |
-
#: functions/interface.
|
|
|
393 |
msgid "Delete"
|
394 |
msgstr "Löschen"
|
395 |
|
396 |
-
#: functions/interface.
|
397 |
-
|
398 |
-
msgstr "Einstellungen gespeichert."
|
399 |
-
|
400 |
-
#: functions/interface.functions.php:67
|
401 |
-
#: functions/interface.functions.php:79
|
402 |
msgid "BackUpWordPress is almost ready."
|
403 |
msgstr "BackUpWordPress ist fast fertig."
|
404 |
|
405 |
-
#: functions/interface.
|
406 |
#, php-format
|
407 |
msgid "The backups directory can't be created because your %1$s directory isn't writable, run %2$s or %3$s or create the folder yourself."
|
408 |
msgstr "Das Backup-Verzeichnis kann nicht erstellt werden, weil dein %1$s-Verzeichnis nicht schreibbar ist. Führe %2$s oder %3$s aus oder erstelle das Verzeichnis selbst."
|
409 |
|
410 |
-
#: functions/interface.
|
411 |
#, php-format
|
412 |
msgid "Your backups directory isn't writable, run %1$s or %2$s or set the permissions yourself."
|
413 |
msgstr "Dein Backup-Verzeichnis ist nicht schreibbar. Führe %1$s oder %2$s aus oder setze die Berechtigungen selbst."
|
414 |
|
415 |
-
#: functions/interface.
|
416 |
#, php-format
|
417 |
msgid "%1$s is running in %2$s. Please contact your host and ask them to disable %3$s."
|
418 |
msgstr "%1$s läuft im %2$s. Bitte kontaktiere deinen Administrator und bitte ihn, den %3$s zu deaktivieren."
|
419 |
|
420 |
-
#: functions/interface.
|
421 |
msgid "http://php.net/manual/en/features.safe-mode.php"
|
422 |
msgstr "http://php.net/manual/de/features.safe-mode.php"
|
423 |
|
424 |
-
#: functions/interface.
|
425 |
msgid "Safe Mode"
|
426 |
msgstr "Safe Mode"
|
427 |
|
428 |
-
#: functions/interface.
|
429 |
-
#, php-format
|
430 |
-
msgid "You have both %1$s and %2$s defined so there isn't anything to back up."
|
431 |
-
msgstr "Du hast sowohl %1$s, als auch %2$s definiert. Deswegen gibt es nichts zu sichern."
|
432 |
-
|
433 |
-
#: functions/interface.functions.php:110
|
434 |
-
#, php-format
|
435 |
-
msgid "The following email address is not valid: %s."
|
436 |
-
msgid_plural "The following email addresses are not valid: %s."
|
437 |
-
msgstr[0] "Die folgende E-Mail-Adresse ist ungültig: %s"
|
438 |
-
msgstr[1] "Die folgenden E-Mail-Adressen sind ungültig: %s"
|
439 |
-
|
440 |
-
#: functions/interface.functions.php:120
|
441 |
-
msgid "The last backup email failed to send. It's likely that the file is too large."
|
442 |
-
msgstr "Das letzte Backup-E-Mail konnte nicht gesendet werden. Wahrscheinlich ist die Datei zu groß."
|
443 |
-
|
444 |
-
#: functions/interface.functions.php:130
|
445 |
#, php-format
|
446 |
msgid "Your custom backups directory %1$s doesn't exist and can't be created, your backups will be saved to %2$s instead."
|
447 |
msgstr "Dein angepasstes Backup-Verzeichnis %1$s existiert nicht und kann nicht erstellt werden, neue Backups werden stattdessen nach %2$s gespeichert."
|
448 |
|
449 |
-
#: functions/interface.
|
450 |
#, php-format
|
451 |
msgid "Your custom backups directory %1$s isn't writable, new backups will be saved to %2$s instead."
|
452 |
msgstr "Dein angepasstes Backup-Verzeichnis %1$s ist nicht schreibbar, neue Backups werden stattdessen nach %2$s gespeichert."
|
453 |
|
454 |
-
#: functions/interface.
|
455 |
-
#, php-format
|
456 |
-
msgid "You have defined a custom exclude list but the following paths don't exist %s, are you sure you entered them correctly?"
|
457 |
-
msgstr "Du hast eine Ausnahmen-Liste definiert, aber die folgenden Pfade existieren nicht: %s. Bist du sicher, dass du sie korrekt eingegeben hast?"
|
458 |
-
|
459 |
-
#: functions/interface.functions.php:160
|
460 |
msgid "BackUpWordPress detected issues with your last backup."
|
461 |
msgstr "BackUpWordPress hat Probleme bei deinem letzten Backup bemerkt."
|
462 |
|
463 |
-
#: functions/
|
464 |
-
msgid "
|
465 |
-
msgstr "Datenbank
|
466 |
|
467 |
-
#: functions/
|
468 |
-
msgid "
|
469 |
-
msgstr "
|
470 |
|
471 |
-
#: functions/
|
472 |
-
msgid "
|
473 |
-
msgstr "
|
474 |
|
475 |
-
#: functions/
|
476 |
-
|
477 |
-
|
478 |
-
msgid "Backup of %s"
|
479 |
-
msgstr "Backup von %s"
|
480 |
|
481 |
-
#: functions/
|
482 |
-
|
483 |
-
|
484 |
-
"BackUpWordPress has completed a backup of your site %1$s.\\n"
|
485 |
-
"\\n"
|
486 |
-
"The backup file should be attached to this email.\\n"
|
487 |
-
"\\n"
|
488 |
-
"You can also download the backup file by clicking the link below:\\n"
|
489 |
-
"\\n"
|
490 |
-
"%2$s\\n"
|
491 |
-
"\\n"
|
492 |
-
"Kind Regards\\n"
|
493 |
-
"\\n"
|
494 |
-
" The Happy BackUpWordPress Backup Emailing Robot"
|
495 |
-
msgstr ""
|
496 |
-
"BackUpWordPress hat ein Backup deiner Seite %1$s fertiggestellt.\n"
|
497 |
-
"\n"
|
498 |
-
"Die Backup-Datei sollte an diese E-Mail angehängt sein.\n"
|
499 |
-
"\n"
|
500 |
-
"Du kannst es auch herunterladen, indem du den folgenden Link anklickst:\n"
|
501 |
-
"\n"
|
502 |
-
"%2$s\n"
|
503 |
-
"\n"
|
504 |
-
"Liebe Grüße\n"
|
505 |
-
"\n"
|
506 |
-
" Der glückliche BackUpWordPress-Backup-E-Mail-Roboter"
|
507 |
|
508 |
-
#: functions/
|
509 |
-
|
510 |
-
|
511 |
-
"BackUpWordPress has completed a backup of your site %1$s.\\n"
|
512 |
-
"\\n"
|
513 |
-
"Unfortunately the backup file was too large to attach to this email.\\n"
|
514 |
-
"\\n"
|
515 |
-
"You can download the backup file by clicking the link below:\\n"
|
516 |
-
"\\n"
|
517 |
-
"%2$s\\n"
|
518 |
-
"\\n"
|
519 |
-
"Kind Regards\\n"
|
520 |
-
"\\n"
|
521 |
-
" The Happy BackUpWordPress Backup Emailing Robot"
|
522 |
-
msgstr ""
|
523 |
-
"BackUpWordPress hat ein Backup deiner Seite %1$s fertiggestellt.\n"
|
524 |
-
"\n"
|
525 |
-
"Leider war die Backup-Datei zu groß, um sie an dieses E-Mail anzuhängen.\n"
|
526 |
-
"\n"
|
527 |
-
"Du kannst es aber herunterladen, indem du den folgenden Link anklickst:\n"
|
528 |
-
"\n"
|
529 |
-
"%2$s\n"
|
530 |
-
"\n"
|
531 |
-
"Liebe Grüße\n"
|
532 |
-
"\n"
|
533 |
-
" Der glückliche BackUpWordPress-Backup-E-Mail-Roboter"
|
534 |
|
535 |
-
#: functions/
|
536 |
-
|
537 |
-
|
538 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
539 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
msgstr ""
|
3 |
"Project-Id-Version: BackUpWordPress\n"
|
4 |
"Report-Msgid-Bugs-To: \n"
|
5 |
+
"POT-Creation-Date: 2012-08-22 15:49+0100\n"
|
6 |
+
"PO-Revision-Date: 2012-08-22 15:49+0100\n"
|
7 |
"Last-Translator: Flo Edelmann <florian-edelmann@online.de>\n"
|
8 |
"Language-Team: Flo Edelmann <florian-edelmann@online.de>\n"
|
9 |
"Language: \n"
|
18 |
"X-Poedit-SourceCharset: utf-8\n"
|
19 |
"X-Poedit-SearchPath-0: .\n"
|
20 |
|
21 |
+
#: plugin.php:52
|
22 |
+
msgid "BackUpWordPress requires PHP version 5.2.4 or greater."
|
23 |
+
msgstr "BackUpWordPress benötigt PHP Version 5.2.4 oder höher."
|
|
|
24 |
|
25 |
+
#: plugin.php:63
|
26 |
#, php-format
|
27 |
+
msgid "BackUpWordPress requires WordPress version %s or greater."
|
28 |
+
msgstr "BackUpWordPress benötigt WordPress Version %s oder größer."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
|
30 |
+
#: plugin.php:95
|
31 |
+
#: admin/schedule-form.php:52
|
32 |
+
msgid "Update"
|
33 |
+
msgstr "Update"
|
34 |
|
35 |
+
#: plugin.php:96
|
36 |
+
msgid "Cancel"
|
37 |
+
msgstr "Abbrechen"
|
38 |
|
39 |
+
#: plugin.php:97
|
40 |
+
msgid ""
|
41 |
+
"Are you sure you want to delete this schedule? All of it's backups will also be deleted.\n"
|
42 |
+
"\n"
|
43 |
+
"'Cancel' to go back, 'OK' to delete.\n"
|
44 |
+
msgstr ""
|
45 |
+
"Bist du sicher, dass du diesen Plan löschen möchtest? Alle enthaltenen Backups werden ebenfalls gelöscht.\n"
|
46 |
+
"\n"
|
47 |
+
"Drücke auf 'Abbrechen' zum Zurückgehen, 'OK' zum Löschen.\n"
|
|
|
|
|
|
|
|
|
|
|
|
|
48 |
|
49 |
+
#: plugin.php:98
|
50 |
+
msgid ""
|
51 |
+
"Are you sure you want to delete this backup?\n"
|
52 |
+
"\n"
|
53 |
+
"'Cancel' to go back, 'OK' to delete.\n"
|
54 |
+
msgstr ""
|
55 |
+
"Bist du sicher, dass du dieses Backup löschen möchtest?\n"
|
56 |
+
"\n"
|
57 |
+
"Drücke auf 'Abbrechen' zum Zurückgehen, 'OK' zum Löschen.\n"
|
58 |
|
59 |
+
#: plugin.php:99
|
60 |
+
msgid ""
|
61 |
+
"Are you sure you want to remove this exclude rule?\n"
|
62 |
+
"\n"
|
63 |
+
"'Cancel' to go back, 'OK' to delete.\n"
|
64 |
+
msgstr ""
|
65 |
+
"Bist du sicher, dass du diese Ausnahmeregel entfernen möchtest?\n"
|
66 |
+
"\n"
|
67 |
+
"Drücke auf 'Abbrechen' zum Zurückgehen, 'OK' zum Löschen.\n"
|
68 |
|
69 |
+
#: plugin.php:100
|
70 |
+
msgid ""
|
71 |
+
"Reducing the number of backups that are stored on this server will cause some of your existing backups to be deleted, are you sure that's what you want?\n"
|
72 |
+
"\n"
|
73 |
+
"'Cancel' to go back, 'OK' to delete.\n"
|
74 |
+
msgstr ""
|
75 |
+
"Wenn du die Anzahl der Backups, die auf diesem Server gespeichert werden, reduzierst, werden einige deiner existierenden Backups gelöscht. Bist du sicher, dass du das willst?\n"
|
76 |
+
"\n"
|
77 |
+
"Drücke auf 'Abbrechen' zum Zurückgehen, 'OK' zum Löschen.\n"
|
78 |
|
79 |
+
#: classes/schedule.php:460
|
80 |
+
msgid "Backup started"
|
81 |
+
msgstr "Backup gestartet"
|
82 |
|
83 |
+
#: classes/schedule.php:511
|
84 |
+
msgid "Creating zip archive"
|
85 |
+
msgstr "ZIP-Archiv wird erstellt"
|
86 |
|
87 |
+
#: classes/schedule.php:517
|
88 |
+
msgid "Dumping database"
|
89 |
+
msgstr "Datenbank wird gedump"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
90 |
|
91 |
+
#: classes/email.php:19
|
92 |
+
msgid "Email notification"
|
93 |
+
msgstr "E-Mail-Benachrichtigung"
|
94 |
|
95 |
+
#: classes/email.php:50
|
96 |
#, php-format
|
97 |
+
msgid "Send an email notification to %s"
|
98 |
+
msgstr "Sende E-Mail-Benachrichtigungen an %s"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
+
#: classes/email.php:72
|
101 |
#, php-format
|
102 |
+
msgid "%s isn't a valid email"
|
103 |
+
msgstr "%s ist keine gültige E-Mail-Adresse"
|
|
|
|
|
104 |
|
105 |
+
#: classes/email.php:127
|
106 |
#, php-format
|
107 |
+
msgid "Backup of %s Failed"
|
108 |
+
msgstr "Backup von %s fehlgeschlagen"
|
|
|
|
|
|
|
|
|
|
|
109 |
|
110 |
+
#: classes/email.php:137
|
|
|
|
|
|
|
|
|
111 |
#, php-format
|
112 |
+
msgid "Backup of %s"
|
113 |
+
msgstr "Backup von %s"
|
114 |
|
115 |
+
#: hm-backup/hm-backup.php:532
|
116 |
+
msgid "The backup file was not created"
|
117 |
+
msgstr "Die Backup-Datei wurde nicht angelegt"
|
118 |
|
119 |
+
#: hm-backup/hm-backup.php:603
|
120 |
+
msgid "The following files are unreadable and couldn't be backed up: "
|
121 |
+
msgstr "Die folgenden Dateien sind nicht lesbar und konnten nicht gesichert werden:"
|
122 |
|
123 |
+
#: admin/constants.php:3
|
124 |
#, php-format
|
125 |
msgid "You can %1$s any of the following %2$s in your %3$s to control advanced settings. %4$s. Defined %5$s will be highlighted."
|
126 |
msgstr "Du kannst jede der folgenden %2$s in deinem %3$s %1$sn, um erweiterte Einstellungen vorzunehmen. %4$s. Definierte %5$s werden hervorgehoben."
|
127 |
|
128 |
+
#: admin/constants.php:3
|
129 |
+
msgid "Constants"
|
130 |
+
msgstr "Konstanten"
|
131 |
+
|
132 |
+
#: admin/constants.php:3
|
133 |
msgid "The Codex can help"
|
134 |
msgstr "Der Codex kann helfen"
|
135 |
|
136 |
+
#: admin/constants.php:8
|
137 |
#, php-format
|
138 |
msgid "The path to folder you would like to store your backup files in, defaults to %s."
|
139 |
msgstr "Der Pfad zum Verzeichnis, in dem du die Backups speichern möchtest. Standard: %s"
|
140 |
|
141 |
+
#: admin/constants.php:8
|
142 |
+
#: admin/constants.php:11
|
143 |
+
#: admin/constants.php:14
|
144 |
+
#: admin/constants.php:17
|
145 |
+
#: admin/constants.php:20
|
146 |
+
#: admin/constants.php:23
|
147 |
+
#: admin/constants.php:26
|
148 |
+
#: admin/constants.php:29
|
149 |
+
#: admin/constants.php:32
|
150 |
+
#: admin/constants.php:35
|
151 |
+
#: admin/constants.php:38
|
152 |
+
#: admin/constants.php:41
|
153 |
+
msgid "e.g."
|
154 |
+
msgstr "z.B."
|
155 |
+
|
156 |
+
#: admin/constants.php:11
|
157 |
#, php-format
|
158 |
msgid "The path to your %1$s executable. Will be used for the %2$s part of the back up if available."
|
159 |
msgstr "Der Pfad zur ausführbaren %1$s-Datei. Wird für den %2$s-Teil des Backups genutzt, wenn verfügbar."
|
160 |
|
161 |
+
#: admin/constants.php:11
|
162 |
+
#: admin/constants.php:14
|
163 |
+
#: admin/constants.php:23
|
164 |
+
#: admin/constants.php:26
|
|
|
|
|
165 |
msgid "database"
|
166 |
msgstr "Datenbank"
|
167 |
|
168 |
+
#: admin/constants.php:14
|
169 |
#, php-format
|
170 |
msgid "The path to your %1$s executable. Will be used to zip up your %2$s and %3$s if available."
|
171 |
msgstr "Der Pfad zur ausführbaren %1$s-Datei. Wird genutzt, um deine %2$s und %3$s als ZIP-Archiv zu komprimieren, wenn verfügbar."
|
172 |
|
173 |
+
#: admin/constants.php:14
|
174 |
+
#: admin/constants.php:23
|
175 |
+
#: admin/constants.php:26
|
|
|
|
|
176 |
msgid "files"
|
177 |
msgstr "Dateien"
|
178 |
|
179 |
+
#: admin/constants.php:17
|
180 |
#, php-format
|
181 |
msgid "Completely disables the automatic back up. You can still back up using the \"Back Up Now\" button. Defaults to %s."
|
182 |
msgstr "Deaktiviert die automatischen Backups vollständig. Du kannst trotzdem Backups erstellen, indem du den \"Jetzt sichern\"-Button verwendest. Standard: %s"
|
183 |
|
184 |
+
#: admin/constants.php:20
|
185 |
#, php-format
|
186 |
msgid "Number of backups to keep, older backups will be deleted automatically when a new backup is completed. Defaults to %s."
|
187 |
msgstr "Anzahl der zu behaltenden Backups. Ältere Backups werden automatisch gelöscht, sobald ein neues Backup fertiggestellt ist. Standard: %s"
|
188 |
|
189 |
+
#: admin/constants.php:23
|
190 |
+
#: admin/constants.php:26
|
191 |
#, php-format
|
192 |
msgid "Backup %1$s only, your %2$s won't be backed up. Defaults to %3$s."
|
193 |
msgstr "Nur die %1$s sichern, deine %2$s werden nicht gesichert. Standard: %3$s"
|
194 |
|
195 |
+
#: admin/constants.php:29
|
196 |
#, php-format
|
197 |
msgid "The time that the daily back up should run. Defaults to %s."
|
198 |
msgstr "Die Zeit, zu der das tägliche Backup laufen soll. Standard: %s"
|
199 |
|
200 |
+
#: admin/constants.php:32
|
201 |
#, php-format
|
202 |
msgid "Attempt to email a copy of your backups. Value should be email address to send backups to. Defaults to %s."
|
203 |
msgstr "Versuche, eine Kopie des Backups per E-Mail zu senden. Der Wert sollte eine E-Mail-Adresse sein. Standard: %s"
|
204 |
|
205 |
+
#: admin/constants.php:35
|
206 |
msgid "Comma separated list of files or directories to exclude, the backups directory is automatically excluded."
|
207 |
msgstr "Kommagetrennte Liste von Dateien oder Verzeichnissen, die ausgeschlossen werden sollen (das Backup-Verzeichnis ist automatisch ausgeschlossen)."
|
208 |
|
209 |
+
#: admin/constants.php:38
|
210 |
#, php-format
|
211 |
msgid "The capability to use when calling %1$s. Defaults to %2$s."
|
212 |
msgstr "Die Rolle, die beim Aufrufen von %1$s benutzt wird. Standard: %2$s"
|
213 |
|
214 |
+
#: admin/constants.php:41
|
215 |
#, php-format
|
216 |
msgid "The root directory that is backed up. Defaults to %s."
|
217 |
msgstr "Das Wurzelverzeichnis, das gesichert wird. Standard: %s"
|
218 |
|
219 |
+
#: admin/schedule-form.php:7
|
220 |
+
msgid "Schedule Settings"
|
221 |
+
msgstr "Plan-Einstellungen"
|
222 |
+
|
223 |
+
#: admin/schedule-form.php:11
|
224 |
+
msgid "Backup"
|
225 |
+
msgstr "Backup"
|
226 |
|
227 |
+
#: admin/schedule-form.php:14
|
228 |
+
msgid "Both Database & files"
|
229 |
+
msgstr "Datenbank & Dateien"
|
230 |
+
|
231 |
+
#: admin/schedule-form.php:15
|
232 |
+
msgid "Files only"
|
233 |
+
msgstr "Dateien"
|
234 |
+
|
235 |
+
#: admin/schedule-form.php:16
|
236 |
+
msgid "Database only"
|
237 |
+
msgstr "Datenbank"
|
238 |
+
|
239 |
+
#: admin/schedule-form.php:23
|
240 |
+
msgid "Schedule"
|
241 |
+
msgstr "Plan"
|
242 |
+
|
243 |
+
#: admin/schedule-form.php:39
|
244 |
+
msgid "Number of backups to store on this server"
|
245 |
+
msgstr "Anzahl der Backups, die auf dem Server gespeichert bleiben"
|
246 |
+
|
247 |
+
#: admin/schedule-form.php:43
|
248 |
+
msgid "The number of previous backups to store on the server. past this limit the oldest backups will be deleted automatically."
|
249 |
+
msgstr "Die Anzahl der vorherigen Backups, die auf dem Server gespeichert bleiben sollen. Über diesem Limit werden die ältesten Backups automatisch gelöscht."
|
250 |
+
|
251 |
+
#: admin/schedule.php:16
|
252 |
+
msgid "hourly on the hour"
|
253 |
+
msgstr ""
|
254 |
+
|
255 |
+
#: admin/schedule.php:16
|
256 |
#, php-format
|
257 |
+
msgid "hourly at %s minutes past the hour"
|
258 |
+
msgstr ""
|
259 |
|
260 |
+
#: admin/schedule.php:22
|
261 |
+
#, php-format
|
262 |
+
msgid "daily at %s"
|
263 |
+
msgstr ""
|
|
|
|
|
|
|
|
|
|
|
|
|
264 |
|
265 |
+
#: admin/schedule.php:34
|
266 |
#, php-format
|
267 |
+
msgid "every 12 hours at %s & %s"
|
268 |
+
msgstr ""
|
269 |
|
270 |
+
#: admin/schedule.php:40
|
271 |
+
#, php-format
|
272 |
+
msgid "weekly on %s at %s"
|
273 |
+
msgstr ""
|
274 |
|
275 |
+
#: admin/schedule.php:46
|
276 |
+
#, php-format
|
277 |
+
msgid "fortnightly on %s at %s"
|
278 |
+
msgstr ""
|
279 |
|
280 |
+
#: admin/schedule.php:53
|
281 |
#, php-format
|
282 |
+
msgid "on the %s of each month at %s"
|
283 |
+
msgstr ""
|
284 |
|
285 |
+
#: admin/schedule.php:59
|
286 |
+
msgid "server"
|
287 |
+
msgstr "Server"
|
288 |
|
289 |
+
#: admin/schedule.php:66
|
290 |
+
#, php-format
|
291 |
+
msgid "store the only the last backup %s"
|
292 |
+
msgstr ""
|
293 |
|
294 |
+
#: admin/schedule.php:72
|
295 |
+
#, php-format
|
296 |
+
msgid "don't store any backups %s"
|
297 |
+
msgstr ""
|
298 |
|
299 |
+
#: admin/schedule.php:78
|
300 |
+
#, php-format
|
301 |
+
msgid "store only the last %s backups %s"
|
302 |
+
msgstr ""
|
303 |
|
304 |
+
#: admin/schedule.php:87
|
305 |
+
#, php-format
|
306 |
+
msgid "Backup my %s %s %s, %s. %s"
|
307 |
+
msgstr ""
|
308 |
+
|
309 |
+
#: admin/schedule.php:87
|
310 |
+
msgid "Backups will be compressed and should be smaller than this."
|
311 |
+
msgstr "Die Backups werden komprimiert und sollten kleiner sein."
|
312 |
|
313 |
+
#: admin/schedule-form-excludes.php:7
|
314 |
+
msgid "Manage Exclude"
|
315 |
+
msgstr "Ausnahmen verwalten"
|
316 |
+
|
317 |
+
#: admin/schedule-form-excludes.php:13
|
318 |
+
msgid "New Exclude Rule"
|
319 |
+
msgstr "Neue Ausnahmeregel"
|
320 |
+
|
321 |
+
#: admin/schedule-form-excludes.php:17
|
322 |
+
msgid "Preview"
|
323 |
+
msgstr "Vorschau"
|
324 |
+
|
325 |
+
#: admin/schedule-form-excludes.php:27
|
326 |
+
msgid "Exclude Rules"
|
327 |
+
msgstr "Ausnahmeregeln"
|
328 |
+
|
329 |
+
#: admin/schedule-form-excludes.php:42
|
330 |
+
msgid "Remove"
|
331 |
+
msgstr "Entfernen"
|
332 |
+
|
333 |
+
#: admin/schedule-form-excludes.php:59
|
334 |
+
msgid "Excluded"
|
335 |
+
msgstr "Ausnehmen"
|
336 |
+
|
337 |
+
#: admin/schedule-form-excludes.php:60
|
338 |
+
msgid "Included"
|
339 |
+
msgstr "Einschließen"
|
340 |
+
|
341 |
+
#: admin/schedule-form-excludes.php:63
|
342 |
+
msgid "Unreadable"
|
343 |
+
msgstr "Nicht lesbar"
|
344 |
+
|
345 |
+
#: admin/schedule-form-excludes.php:86
|
346 |
+
msgid "Unreadable files can't be backed up"
|
347 |
+
msgstr "Nicht lesbare Dateien können nicht gesichert werden"
|
348 |
+
|
349 |
+
#: admin/schedule-form-excludes.php:92
|
350 |
#, php-format
|
351 |
+
msgid "Your site is %s. Backups will be compressed and so will be smaller."
|
352 |
+
msgstr "Deine Seite ist %s groß. Die Backups werden komprimiert und sollten kleiner sein."
|
353 |
+
|
354 |
+
#: admin/schedule-form-excludes.php:98
|
355 |
+
msgid "Close"
|
356 |
+
msgstr "Schließen"
|
357 |
+
|
358 |
+
#: admin/actions.php:163
|
359 |
+
msgid "BackUpWordPress has detected a problem."
|
360 |
+
msgstr "BackUpWordPress hat ein Problem entdeckt."
|
361 |
|
362 |
+
#: admin/actions.php:163
|
363 |
#, php-format
|
364 |
+
msgid "%1$s is returning a %2$s response which could mean cron jobs aren't getting fired properly. BackUpWordPress relies on wp-cron to run scheduled back ups. See the %3$s for more details."
|
365 |
+
msgstr "%1$s gibt eine %2$s-Antwort zurück. Das könnte bedeuten, dass deine Cron-Jobs nicht richtig aufgerufen werden. BackUpWordPress benutzt wp-cron, um geplante Backups auszuführen. Sieh dir das %3$s an für mehr Details."
|
366 |
|
367 |
+
#: admin/actions.php:232
|
368 |
+
msgid "Backup type cannot be empty"
|
369 |
+
msgstr "Backup-Typ kann nicht leer sein"
|
370 |
|
371 |
+
#: admin/actions.php:235
|
372 |
+
msgid "Invalid backup type"
|
373 |
+
msgstr "Ungültiger Backup-Typ"
|
374 |
|
375 |
+
#: admin/actions.php:245
|
376 |
+
msgid "Schedule cannot be empty"
|
377 |
+
msgstr "Aufgaben können nicht leer sein"
|
378 |
+
|
379 |
+
#: admin/actions.php:248
|
380 |
+
msgid "Invalid schedule"
|
381 |
+
msgstr "Ungültige Aufgaben"
|
382 |
+
|
383 |
+
#: admin/actions.php:258
|
384 |
+
msgid "Max backups must be more than 1"
|
385 |
+
msgstr "Maximale Anzahl der Backups muss größer als 1 sein"
|
386 |
+
|
387 |
+
#: admin/actions.php:261
|
388 |
+
msgid "Max backups must be a number"
|
389 |
+
msgstr "Maximale Anzahl der Backups muss eine Nummer sein"
|
390 |
+
|
391 |
+
#: admin/actions.php:334
|
392 |
#, php-format
|
393 |
+
msgid "%s matches 1 file."
|
394 |
+
msgid_plural "%s matches %d files"
|
395 |
+
msgstr[0] "%s passt auf eine Datei."
|
396 |
+
msgstr[1] "%s passt auf %d Dateien."
|
397 |
|
398 |
+
#: admin/actions.php:338
|
399 |
#, php-format
|
400 |
+
msgid "%s didn't match any files."
|
401 |
+
msgstr "%s passt auf keine Dateien."
|
402 |
+
|
403 |
+
#: admin/page.php:5
|
404 |
+
msgid "Manage Backups"
|
405 |
+
msgstr "Backups verwalten"
|
406 |
+
|
407 |
+
#: admin/page.php:13
|
408 |
+
msgid "You need to fix the issues detailed above before BackUpWordPress can start."
|
409 |
+
msgstr "Du musst die Probleme, die oben beschrieben werden, beheben, bevor BackUpWordPress starten kann."
|
410 |
|
411 |
+
#: admin/page.php:17
|
412 |
#, php-format
|
413 |
+
msgid "If you need help getting things working you are more than welcome to email us at %s and we'll do what we can."
|
414 |
+
msgstr "Wenn du Hilfe brauchst, sende uns ruhig eine E-Mail an %s (am besten auf Englisch) und wir werden tun, was wir können."
|
415 |
|
416 |
+
#: admin/backups.php:13
|
417 |
+
msgid "add schedule"
|
418 |
+
msgstr "Aufgabe hinzufügen"
|
419 |
|
420 |
+
#: admin/backups.php:36
|
421 |
#, php-format
|
422 |
+
msgid "1 backup completed"
|
423 |
+
msgid_plural "%d backups completed"
|
424 |
+
msgstr[0] "1 Backup fertiggestellt"
|
425 |
+
msgstr[1] "%d Backups fertiggestellt"
|
426 |
|
427 |
+
#: admin/backups.php:37
|
428 |
+
msgid "Size"
|
429 |
+
msgstr "Größe"
|
430 |
+
|
431 |
+
#: admin/backups.php:38
|
432 |
+
msgid "Type"
|
433 |
+
msgstr "Typ"
|
434 |
+
|
435 |
+
#: admin/backups.php:39
|
436 |
+
msgid "Actions"
|
437 |
+
msgstr "Aktionen"
|
438 |
+
|
439 |
+
#: admin/backups.php:62
|
440 |
+
msgid "This is where your backups will appear once you have one."
|
441 |
+
msgstr "Hier erscheinen deine Backups, sobald du welche hast."
|
442 |
+
|
443 |
+
#: admin/menu.php:10
|
444 |
+
#: admin/menu.php:34
|
445 |
+
msgid "Backups"
|
446 |
+
msgstr "Backups"
|
447 |
+
|
448 |
+
#: admin/menu.php:69
|
449 |
+
msgid "You are not using the latest stable version of BackUpWordPress"
|
450 |
+
msgstr "Du benutzt nicht die neueste stabile BackUpWordPress-Version"
|
451 |
+
|
452 |
+
#: admin/menu.php:69
|
453 |
#, php-format
|
454 |
+
msgid "The information below is for version %1$s. View the %2$s file for help specific to version %3$s."
|
455 |
+
msgstr "Diese Informationen sind für Version %1$s. Sieh dir die %2$s-Datei für Hilfe speziell für Version %3$s an."
|
456 |
|
457 |
+
#: admin/menu.php:75
|
458 |
+
msgid "FAQ"
|
459 |
+
msgstr "FAQ"
|
460 |
|
461 |
+
#: admin/menu.php:79
|
462 |
+
msgid "For more information:"
|
463 |
+
msgstr "Für mehr Informationen:"
|
464 |
+
|
465 |
+
#: admin/menu.php:81
|
466 |
+
msgid "Support Forums"
|
467 |
+
msgstr "Support-Foren"
|
468 |
+
|
469 |
+
#: admin/menu.php:82
|
470 |
+
msgid "Help with translation"
|
471 |
+
msgstr "Beim Übersetzen helfen"
|
472 |
+
|
473 |
+
#: functions/core.php:192
|
474 |
+
msgid "BackUpWordPress has setup your default schedules."
|
475 |
+
msgstr "BackUpWordPress hat deine Standard-Pläne eingerichtet."
|
476 |
+
|
477 |
+
#: functions/core.php:192
|
478 |
+
msgid "By default BackUpWordPress performs a daily backup of your database and a weekly backup of your database & files. You can modify these schedules below."
|
479 |
+
msgstr "Standardmäßig macht BackUpWordPress täglich ein Backup deiner Datenbank und wöchentlich eines deiner Datenbank und deiner Dateien. Du kannst diese Pläne hier bearbeiten."
|
480 |
|
481 |
+
#: functions/core.php:273
|
482 |
+
#, php-format
|
483 |
+
msgid "This %s file ensures that other people cannot download your backup files."
|
484 |
+
msgstr "Diese %s-Datei garantiert, dass andere Leute nicht deine Backup-Dateien herunterladen können."
|
485 |
+
|
486 |
+
#: functions/interface.php:27
|
487 |
msgid "Download"
|
488 |
msgstr "Download"
|
489 |
|
490 |
+
#: functions/interface.php:28
|
491 |
+
#: functions/interface.php:215
|
492 |
msgid "Delete"
|
493 |
msgstr "Löschen"
|
494 |
|
495 |
+
#: functions/interface.php:50
|
496 |
+
#: functions/interface.php:62
|
|
|
|
|
|
|
|
|
497 |
msgid "BackUpWordPress is almost ready."
|
498 |
msgstr "BackUpWordPress ist fast fertig."
|
499 |
|
500 |
+
#: functions/interface.php:50
|
501 |
#, php-format
|
502 |
msgid "The backups directory can't be created because your %1$s directory isn't writable, run %2$s or %3$s or create the folder yourself."
|
503 |
msgstr "Das Backup-Verzeichnis kann nicht erstellt werden, weil dein %1$s-Verzeichnis nicht schreibbar ist. Führe %2$s oder %3$s aus oder erstelle das Verzeichnis selbst."
|
504 |
|
505 |
+
#: functions/interface.php:62
|
506 |
#, php-format
|
507 |
msgid "Your backups directory isn't writable, run %1$s or %2$s or set the permissions yourself."
|
508 |
msgstr "Dein Backup-Verzeichnis ist nicht schreibbar. Führe %1$s oder %2$s aus oder setze die Berechtigungen selbst."
|
509 |
|
510 |
+
#: functions/interface.php:72
|
511 |
#, php-format
|
512 |
msgid "%1$s is running in %2$s. Please contact your host and ask them to disable %3$s."
|
513 |
msgstr "%1$s läuft im %2$s. Bitte kontaktiere deinen Administrator und bitte ihn, den %3$s zu deaktivieren."
|
514 |
|
515 |
+
#: functions/interface.php:72
|
516 |
msgid "http://php.net/manual/en/features.safe-mode.php"
|
517 |
msgstr "http://php.net/manual/de/features.safe-mode.php"
|
518 |
|
519 |
+
#: functions/interface.php:72
|
520 |
msgid "Safe Mode"
|
521 |
msgstr "Safe Mode"
|
522 |
|
523 |
+
#: functions/interface.php:82
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
524 |
#, php-format
|
525 |
msgid "Your custom backups directory %1$s doesn't exist and can't be created, your backups will be saved to %2$s instead."
|
526 |
msgstr "Dein angepasstes Backup-Verzeichnis %1$s existiert nicht und kann nicht erstellt werden, neue Backups werden stattdessen nach %2$s gespeichert."
|
527 |
|
528 |
+
#: functions/interface.php:92
|
529 |
#, php-format
|
530 |
msgid "Your custom backups directory %1$s isn't writable, new backups will be saved to %2$s instead."
|
531 |
msgstr "Dein angepasstes Backup-Verzeichnis %1$s ist nicht schreibbar, neue Backups werden stattdessen nach %2$s gespeichert."
|
532 |
|
533 |
+
#: functions/interface.php:102
|
|
|
|
|
|
|
|
|
|
|
534 |
msgid "BackUpWordPress detected issues with your last backup."
|
535 |
msgstr "BackUpWordPress hat Probleme bei deinem letzten Backup bemerkt."
|
536 |
|
537 |
+
#: functions/interface.php:182
|
538 |
+
msgid "Database and Files"
|
539 |
+
msgstr "Datenbank und Dateien"
|
540 |
|
541 |
+
#: functions/interface.php:185
|
542 |
+
msgid "Files"
|
543 |
+
msgstr "Dateien"
|
544 |
|
545 |
+
#: functions/interface.php:188
|
546 |
+
msgid "Database"
|
547 |
+
msgstr "Datenbank"
|
548 |
|
549 |
+
#: functions/interface.php:193
|
550 |
+
msgid "Unknown"
|
551 |
+
msgstr "Unbekannt"
|
|
|
|
|
552 |
|
553 |
+
#: functions/interface.php:201
|
554 |
+
msgid "cancel"
|
555 |
+
msgstr "abbrechen"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
556 |
|
557 |
+
#: functions/interface.php:207
|
558 |
+
msgid "Settings"
|
559 |
+
msgstr "Einstellungen"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
560 |
|
561 |
+
#: functions/interface.php:210
|
562 |
+
msgid "Excludes"
|
563 |
+
msgstr "Ausnahmen"
|
564 |
+
|
565 |
+
#: functions/interface.php:213
|
566 |
+
msgid "Run now"
|
567 |
+
msgstr "Jetzt ausführen"
|
568 |
+
|
569 |
+
#~ msgid ""
|
570 |
+
#~ "You can define %1$s in your %2$s to control some settings. A full list of "
|
571 |
+
#~ "%3$s can be found in the %4$s. Defined settings will not be editable "
|
572 |
+
#~ "below."
|
573 |
+
#~ msgstr ""
|
574 |
+
#~ "Du kannst %1$s in deinem %2$s definieren, um einige Einstellungen "
|
575 |
+
#~ "vorzunehmen. Eine komplette Liste der %3$s kannst du im %4$s finden. "
|
576 |
+
#~ "Definierte Einstellungen sind unten nicht veränderbar."
|
577 |
+
|
578 |
+
#~ msgid "help panel"
|
579 |
+
#~ msgstr "Hilfe-Panel"
|
580 |
+
|
581 |
+
#~ msgid "Automatic Backups"
|
582 |
+
#~ msgstr "Automatische Backups"
|
583 |
+
|
584 |
+
#~ msgid "Backup my site automatically."
|
585 |
+
#~ msgstr "Sichere meine Seite automatisch."
|
586 |
+
|
587 |
+
#~ msgid "No automatic backups."
|
588 |
+
#~ msgstr "Keine automatischen Backups."
|
589 |
+
|
590 |
+
#~ msgid "Frequency of backups"
|
591 |
+
#~ msgstr "Häufigkeit der Backups"
|
592 |
+
|
593 |
+
#~ msgid "Automatic backups will occur"
|
594 |
+
#~ msgstr "Automatische Backups werden ausgeführt:"
|
595 |
+
|
596 |
+
#~ msgid "Daily"
|
597 |
+
#~ msgstr "Täglich"
|
598 |
+
|
599 |
+
#~ msgid "Weekly"
|
600 |
+
#~ msgstr "Wöchentlich"
|
601 |
+
|
602 |
+
#~ msgid "Fortnightly"
|
603 |
+
#~ msgstr "Vierzehntägig"
|
604 |
+
|
605 |
+
#~ msgid "Monthly"
|
606 |
+
#~ msgstr "Monatlich"
|
607 |
+
|
608 |
+
#~ msgid "What to Backup"
|
609 |
+
#~ msgstr "Zu sichernde Daten"
|
610 |
+
|
611 |
+
#~ msgid "Backup my"
|
612 |
+
#~ msgstr "Sichere meine"
|
613 |
+
|
614 |
+
#~ msgid "Number of backups"
|
615 |
+
#~ msgstr "Anzahl der Backups"
|
616 |
+
|
617 |
+
#~ msgid "Email backups"
|
618 |
+
#~ msgstr "Backup-E-Mail"
|
619 |
+
|
620 |
+
#~ msgid ""
|
621 |
+
#~ "A copy of the backup file will be emailed to this address. Disabled if "
|
622 |
+
#~ "left blank."
|
623 |
+
#~ msgstr ""
|
624 |
+
#~ "Eine Kopie der Backup-Datei wird per E-Mail an diese Adresse gesendet. "
|
625 |
+
#~ "Leerlassen zum deaktivieren."
|
626 |
|
627 |
+
#~ msgid ""
|
628 |
+
#~ "A comma separated list of file and directory paths that you do "
|
629 |
+
#~ "<strong>not</strong> want to backup."
|
630 |
+
#~ msgstr ""
|
631 |
+
#~ "Eine kommagetrennte Liste von Datei- und Verzeichnispfaden, die du "
|
632 |
+
#~ "<strong>nicht</strong> sichern möchtest."
|
633 |
+
|
634 |
+
#~ msgid "Save Changes"
|
635 |
+
#~ msgstr "Änderungen speichern"
|
636 |
+
|
637 |
+
#~ msgid "Only the most recent backup will be saved"
|
638 |
+
|
639 |
+
#~ msgid_plural "The %d most recent backups will be saved"
|
640 |
+
#~ msgstr[0] "Nur das neueste Backup wird gespeichert"
|
641 |
+
#~ msgstr[1] "Die %d neuesten Backups werden gespeichert"
|
642 |
+
|
643 |
+
#~ msgid "Total %s"
|
644 |
+
#~ msgstr "Insgesamt %s"
|
645 |
+
|
646 |
+
#~ msgid "Back Up Now"
|
647 |
+
#~ msgstr "Jetzt sichern"
|
648 |
+
|
649 |
+
#~ msgid "You have entered an invalid number of backups."
|
650 |
+
#~ msgstr "Du hast eine ungültige Anzahl von Backups eingegeben."
|
651 |
+
|
652 |
+
#~ msgid "Automatic backups are %s."
|
653 |
+
#~ msgstr "Automatische Backups sind %s."
|
654 |
+
|
655 |
+
#~ msgid "disabled"
|
656 |
+
#~ msgstr "deaktiviert"
|
657 |
+
|
658 |
+
#~ msgid "&"
|
659 |
+
#~ msgstr "&"
|
660 |
+
|
661 |
+
#~ msgid ""
|
662 |
+
#~ "Your %1$s will be automatically backed up %2$s. The next backup will "
|
663 |
+
#~ "occur at %3$s on %4$s and be saved to %5$s."
|
664 |
+
|
665 |
+
#~ msgid_plural ""
|
666 |
+
#~ "Your %1$s will be automatically backed up %2$s. The next backup will "
|
667 |
+
#~ "occur at %3$s on %4$s and be saved to %5$s."
|
668 |
+
#~ msgstr[0] ""
|
669 |
+
#~ "Deine %1$s wird automatisch %2$s gesichert. Das nächste Backup findet am "
|
670 |
+
#~ "%4$s um %3$s statt und wird nach %5$s gespeichert."
|
671 |
+
#~ msgstr[1] ""
|
672 |
+
#~ "Deine %1$s werden automatisch %2$s gesichert. Das nächste Backup findet "
|
673 |
+
#~ "am %3$s um %4$s statt und wird nach %5$s gespeichert."
|
674 |
+
|
675 |
+
#~ msgid "It's currently %s"
|
676 |
+
#~ msgstr "Es ist jetzt %s"
|
677 |
+
|
678 |
+
#~ msgid "Calculating Size..."
|
679 |
+
#~ msgstr "Größe berechnen..."
|
680 |
+
|
681 |
+
#~ msgid "A copy of each backup will be emailed to %s."
|
682 |
+
#~ msgstr "Eine Kopie jedes Backups wird an %s gesendet."
|
683 |
+
|
684 |
+
#~ msgid "The following paths will be excluded from your backups %s."
|
685 |
+
#~ msgstr ""
|
686 |
+
#~ "Die folgenden Pfade werden von deinen Backups ausgeschlossen sein: %s"
|
687 |
+
|
688 |
+
#~ msgid "Settings saved."
|
689 |
+
#~ msgstr "Einstellungen gespeichert."
|
690 |
+
|
691 |
+
#~ msgid ""
|
692 |
+
#~ "You have both %1$s and %2$s defined so there isn't anything to back up."
|
693 |
+
#~ msgstr ""
|
694 |
+
#~ "Du hast sowohl %1$s, als auch %2$s definiert. Deswegen gibt es nichts zu "
|
695 |
+
#~ "sichern."
|
696 |
+
|
697 |
+
#~ msgid "The following email address is not valid: %s."
|
698 |
+
|
699 |
+
#~ msgid_plural "The following email addresses are not valid: %s."
|
700 |
+
#~ msgstr[0] "Die folgende E-Mail-Adresse ist ungültig: %s"
|
701 |
+
#~ msgstr[1] "Die folgenden E-Mail-Adressen sind ungültig: %s"
|
702 |
+
|
703 |
+
#~ msgid ""
|
704 |
+
#~ "The last backup email failed to send. It's likely that the file is too "
|
705 |
+
#~ "large."
|
706 |
+
#~ msgstr ""
|
707 |
+
#~ "Das letzte Backup-E-Mail konnte nicht gesendet werden. Wahrscheinlich ist "
|
708 |
+
#~ "die Datei zu groß."
|
709 |
+
|
710 |
+
#~ msgid ""
|
711 |
+
#~ "You have defined a custom exclude list but the following paths don't "
|
712 |
+
#~ "exist %s, are you sure you entered them correctly?"
|
713 |
+
#~ msgstr ""
|
714 |
+
#~ "Du hast eine Ausnahmen-Liste definiert, aber die folgenden Pfade "
|
715 |
+
#~ "existieren nicht: %s. Bist du sicher, dass du sie korrekt eingegeben hast?"
|
716 |
+
|
717 |
+
#~ msgid "Removing old backups"
|
718 |
+
#~ msgstr "Alte Backups werden gelöscht"
|
719 |
+
|
720 |
+
#~ msgid ""
|
721 |
+
#~ "BackUpWordPress has completed a backup of your site %1$s.\\n\\nThe backup "
|
722 |
+
#~ "file should be attached to this email.\\n\\nYou can also download the "
|
723 |
+
#~ "backup file by clicking the link below:\\n\\n%2$s\\n\\nKind Regards\\n\\n "
|
724 |
+
#~ "The Happy BackUpWordPress Backup Emailing Robot"
|
725 |
+
#~ msgstr ""
|
726 |
+
#~ "BackUpWordPress hat ein Backup deiner Seite %1$s fertiggestellt.\n"
|
727 |
+
#~ "\n"
|
728 |
+
#~ "Die Backup-Datei sollte an diese E-Mail angehängt sein.\n"
|
729 |
+
#~ "\n"
|
730 |
+
#~ "Du kannst es auch herunterladen, indem du den folgenden Link anklickst:\n"
|
731 |
+
#~ "\n"
|
732 |
+
#~ "%2$s\n"
|
733 |
+
#~ "\n"
|
734 |
+
#~ "Liebe Grüße\n"
|
735 |
+
#~ "\n"
|
736 |
+
#~ " Der glückliche BackUpWordPress-Backup-E-Mail-Roboter"
|
737 |
+
|
738 |
+
#~ msgid ""
|
739 |
+
#~ "BackUpWordPress has completed a backup of your site %1$s.\\n"
|
740 |
+
#~ "\\nUnfortunately the backup file was too large to attach to this email.\\n"
|
741 |
+
#~ "\\nYou can download the backup file by clicking the link below:\\n\\n%2$s"
|
742 |
+
#~ "\\n\\nKind Regards\\n\\n The Happy BackUpWordPress Backup Emailing Robot"
|
743 |
+
#~ msgstr ""
|
744 |
+
#~ "BackUpWordPress hat ein Backup deiner Seite %1$s fertiggestellt.\n"
|
745 |
+
#~ "\n"
|
746 |
+
#~ "Leider war die Backup-Datei zu groß, um sie an dieses E-Mail anzuhängen.\n"
|
747 |
+
#~ "\n"
|
748 |
+
#~ "Du kannst es aber herunterladen, indem du den folgenden Link anklickst:\n"
|
749 |
+
#~ "\n"
|
750 |
+
#~ "%2$s\n"
|
751 |
+
#~ "\n"
|
752 |
+
#~ "Liebe Grüße\n"
|
753 |
+
#~ "\n"
|
754 |
+
#~ " Der glückliche BackUpWordPress-Backup-E-Mail-Roboter"
|
plugin.php
CHANGED
@@ -5,11 +5,11 @@ 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 → Backups</strong>.
|
7 |
Author: Human Made Limited
|
8 |
-
Version:
|
9 |
Author URI: http://hmn.md/
|
10 |
*/
|
11 |
|
12 |
-
/* Copyright 2011 Human Made Limited (email :
|
13 |
|
14 |
This program is free software; you can redistribute it and/or modify
|
15 |
it under the terms of the GNU General Public License as published by
|
@@ -27,13 +27,18 @@ Author URI: http://hmn.md/
|
|
27 |
*/
|
28 |
|
29 |
define( 'HMBKP_PLUGIN_SLUG', 'backupwordpress' );
|
30 |
-
define( 'HMBKP_PLUGIN_PATH',
|
31 |
-
define( 'HMBKP_PLUGIN_URL',
|
32 |
-
|
|
|
|
|
|
|
|
|
33 |
|
34 |
if ( ! defined( 'HMBKP_SECURE_KEY' ) )
|
35 |
define( 'HMBKP_SECURE_KEY', md5( ABSPATH . time() ) );
|
36 |
|
|
|
37 |
if ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) )
|
38 |
define( 'WP_MAX_MEMORY_LIMIT', '256M' );
|
39 |
|
@@ -41,7 +46,7 @@ if ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) )
|
|
41 |
if ( version_compare( phpversion(), '5.2.4', '<' ) ) {
|
42 |
|
43 |
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
44 |
-
deactivate_plugins(
|
45 |
|
46 |
if ( isset( $_GET['action'] ) && ( $_GET['action'] == 'activate' || $_GET['action'] == 'error_scrape' ) )
|
47 |
die( __( 'BackUpWordPress requires PHP version 5.2.4 or greater.', 'hmbkp' ) );
|
@@ -49,13 +54,13 @@ if ( version_compare( phpversion(), '5.2.4', '<' ) ) {
|
|
49 |
}
|
50 |
|
51 |
// Don't activate on old versions of WordPress
|
52 |
-
if ( version_compare( get_bloginfo('version'), HMBKP_REQUIRED_WP_VERSION, '<' ) ) {
|
53 |
|
54 |
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
55 |
-
deactivate_plugins(
|
56 |
|
57 |
if ( isset( $_GET['action'] ) && ( $_GET['action'] == 'activate' || $_GET['action'] == 'error_scrape' ) )
|
58 |
-
die( sprintf( __( 'BackUpWordPress requires WordPress version %s.', 'hmbkp' ), HMBKP_REQUIRED_WP_VERSION ) );
|
59 |
|
60 |
}
|
61 |
|
@@ -64,82 +69,79 @@ if ( version_compare( get_bloginfo('version'), HMBKP_REQUIRED_WP_VERSION, '<' )
|
|
64 |
*
|
65 |
* @return null
|
66 |
*/
|
67 |
-
function
|
68 |
|
69 |
$plugin_data = get_plugin_data( __FILE__ );
|
70 |
|
|
|
71 |
define( 'HMBKP_VERSION', $plugin_data['Version'] );
|
72 |
|
|
|
73 |
load_plugin_textdomain( 'hmbkp', false, HMBKP_PLUGIN_SLUG . '/languages/' );
|
74 |
|
75 |
// Fire the update action
|
76 |
-
if ( HMBKP_VERSION
|
77 |
hmbkp_update();
|
78 |
|
79 |
// Load admin css and js
|
80 |
if ( isset( $_GET['page'] ) && $_GET['page'] == HMBKP_PLUGIN_SLUG ) {
|
81 |
-
wp_enqueue_script( 'hmbkp', HMBKP_PLUGIN_URL . '/assets/hmbkp.js' );
|
82 |
-
wp_enqueue_style( 'hmbkp', HMBKP_PLUGIN_URL . '/assets/hmbkp.css' );
|
83 |
-
}
|
84 |
-
|
85 |
-
// Handle any advanced option changes
|
86 |
-
hmbkp_constant_changes();
|
87 |
-
|
88 |
-
}
|
89 |
-
add_action( 'admin_init', 'hmbkp_actions' );
|
90 |
-
|
91 |
-
/**
|
92 |
-
* Setup the HM_Backup class
|
93 |
-
*
|
94 |
-
* @return null
|
95 |
-
*/
|
96 |
-
function hmbkp_setup_hm_backup() {
|
97 |
|
98 |
-
|
|
|
99 |
|
100 |
-
|
101 |
-
|
102 |
-
|
|
|
|
|
|
|
|
|
|
|
103 |
|
104 |
-
|
105 |
-
|
106 |
|
107 |
-
|
108 |
-
$hm_backup->zip_command_path = HMBKP_ZIP_PATH;
|
109 |
|
110 |
-
|
111 |
-
$hm_backup->root = HMBKP_ROOT;
|
112 |
|
113 |
-
|
|
|
|
|
114 |
|
115 |
}
|
116 |
-
add_action( '
|
117 |
|
118 |
// Load the admin menu
|
119 |
-
require_once( HMBKP_PLUGIN_PATH . '/admin.
|
120 |
-
require_once( HMBKP_PLUGIN_PATH . '/admin
|
121 |
|
122 |
// Load hm-backup
|
123 |
if ( ! class_exists( 'HM_Backup' ) )
|
124 |
require_once( HMBKP_PLUGIN_PATH . '/hm-backup/hm-backup.php' );
|
125 |
|
|
|
|
|
|
|
|
|
126 |
// Load the core functions
|
127 |
-
require_once( HMBKP_PLUGIN_PATH . '/functions/
|
128 |
-
require_once( HMBKP_PLUGIN_PATH . '/functions/
|
129 |
-
|
130 |
-
|
|
|
|
|
|
|
|
|
131 |
|
132 |
// Load the wp cli command
|
133 |
if ( defined( 'WP_CLI' ) && WP_CLI )
|
134 |
-
include( HMBKP_PLUGIN_PATH . '/
|
135 |
|
|
|
136 |
if ( ! defined( 'PCLZIP_TEMPORARY_DIR' ) )
|
137 |
define( 'PCLZIP_TEMPORARY_DIR', trailingslashit( hmbkp_path() ) );
|
138 |
|
139 |
-
//
|
140 |
add_action( 'activate_' . HMBKP_PLUGIN_SLUG . '/plugin.php', 'hmbkp_activate' );
|
141 |
add_action( 'deactivate_' . HMBKP_PLUGIN_SLUG . '/plugin.php', 'hmbkp_deactivate' );
|
142 |
-
|
143 |
-
// Cron hook for backups
|
144 |
-
add_action( 'hmbkp_schedule_backup_hook', 'hmbkp_do_backup' );
|
145 |
-
add_action( 'hmbkp_schedule_single_backup_hook', 'hmbkp_do_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 → Backups</strong>.
|
7 |
Author: Human Made Limited
|
8 |
+
Version: 2.0.1
|
9 |
Author URI: http://hmn.md/
|
10 |
*/
|
11 |
|
12 |
+
/* Copyright 2011 Human Made Limited (email : support@hmn.md)
|
13 |
|
14 |
This program is free software; you can redistribute it and/or modify
|
15 |
it under the terms of the GNU General Public License as published by
|
27 |
*/
|
28 |
|
29 |
define( 'HMBKP_PLUGIN_SLUG', 'backupwordpress' );
|
30 |
+
define( 'HMBKP_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
|
31 |
+
define( 'HMBKP_PLUGIN_URL', plugins_url( HMBKP_PLUGIN_SLUG ) );
|
32 |
+
|
33 |
+
if ( ! defined( 'HMBKP_REQUIRED_WP_VERSION' ) )
|
34 |
+
define( 'HMBKP_REQUIRED_WP_VERSION', '3.3.2' );
|
35 |
+
|
36 |
+
define( 'HMBKP_ADMIN_URL', add_query_arg( 'page', HMBKP_PLUGIN_SLUG, admin_url( 'tools.php' ) ) );
|
37 |
|
38 |
if ( ! defined( 'HMBKP_SECURE_KEY' ) )
|
39 |
define( 'HMBKP_SECURE_KEY', md5( ABSPATH . time() ) );
|
40 |
|
41 |
+
// Max memory limit isn't defined in old versions of WordPress
|
42 |
if ( ! defined( 'WP_MAX_MEMORY_LIMIT' ) )
|
43 |
define( 'WP_MAX_MEMORY_LIMIT', '256M' );
|
44 |
|
46 |
if ( version_compare( phpversion(), '5.2.4', '<' ) ) {
|
47 |
|
48 |
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
49 |
+
deactivate_plugins( __FILE__ );
|
50 |
|
51 |
if ( isset( $_GET['action'] ) && ( $_GET['action'] == 'activate' || $_GET['action'] == 'error_scrape' ) )
|
52 |
die( __( 'BackUpWordPress requires PHP version 5.2.4 or greater.', 'hmbkp' ) );
|
54 |
}
|
55 |
|
56 |
// Don't activate on old versions of WordPress
|
57 |
+
if ( version_compare( get_bloginfo( 'version' ), HMBKP_REQUIRED_WP_VERSION, '<' ) ) {
|
58 |
|
59 |
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
60 |
+
deactivate_plugins( __FILE__ );
|
61 |
|
62 |
if ( isset( $_GET['action'] ) && ( $_GET['action'] == 'activate' || $_GET['action'] == 'error_scrape' ) )
|
63 |
+
die( sprintf( __( 'BackUpWordPress requires WordPress version %s or greater.', 'hmbkp' ), HMBKP_REQUIRED_WP_VERSION ) );
|
64 |
|
65 |
}
|
66 |
|
69 |
*
|
70 |
* @return null
|
71 |
*/
|
72 |
+
function hmbkp_init() {
|
73 |
|
74 |
$plugin_data = get_plugin_data( __FILE__ );
|
75 |
|
76 |
+
// define the plugin version
|
77 |
define( 'HMBKP_VERSION', $plugin_data['Version'] );
|
78 |
|
79 |
+
// Load translations
|
80 |
load_plugin_textdomain( 'hmbkp', false, HMBKP_PLUGIN_SLUG . '/languages/' );
|
81 |
|
82 |
// Fire the update action
|
83 |
+
if ( HMBKP_VERSION != get_option( 'hmbkp_plugin_version' ) )
|
84 |
hmbkp_update();
|
85 |
|
86 |
// Load admin css and js
|
87 |
if ( isset( $_GET['page'] ) && $_GET['page'] == HMBKP_PLUGIN_SLUG ) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
88 |
|
89 |
+
wp_enqueue_script( 'hmbkp_fancybox', HMBKP_PLUGIN_URL . '/assets/fancyBox/source/jquery.fancybox.js', array( 'jquery' ), HMBKP_VERSION );
|
90 |
+
wp_enqueue_script( 'hmbkp', HMBKP_PLUGIN_URL . '/assets/hmbkp.js', array( 'jquery-ui-tabs', 'jquery-ui-widget', 'hmbkp_fancybox' ), HMBKP_VERSION );
|
91 |
|
92 |
+
wp_localize_script( 'hmbkp', 'objectL10n', array(
|
93 |
+
'update' => __( 'Update', 'hmbkp' ),
|
94 |
+
'cancel' => __( 'Cancel', 'hmbkp' ),
|
95 |
+
'delete_schedule' => __( 'Are you sure you want to delete this schedule? All of it\'s backups will also be deleted.' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'hmbkp' ) . "\n",
|
96 |
+
'delete_backup' => __( 'Are you sure you want to delete this backup?', 'hmbkp' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'hmbkp' ) . "\n",
|
97 |
+
'remove_exclude_rule' => __( 'Are you sure you want to remove this exclude rule?', 'hmbkp' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'hmbkp' ) . "\n",
|
98 |
+
'remove_old_backups' => __( 'Reducing the number of backups that are stored on this server will cause some of your existing backups to be deleted, are you sure that\'s what you want?', 'hmbkp' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'hmbkp' ) . "\n"
|
99 |
+
) );
|
100 |
|
101 |
+
wp_enqueue_style( 'hmbkp_fancybox', HMBKP_PLUGIN_URL . '/assets/fancyBox/source/jquery.fancybox.css', false, HMBKP_VERSION );
|
102 |
+
wp_enqueue_style( 'hmbkp', HMBKP_PLUGIN_URL . '/assets/hmbkp.css', false, HMBKP_VERSION );
|
103 |
|
104 |
+
}
|
|
|
105 |
|
106 |
+
hmbkp_setup_default_schedules();
|
|
|
107 |
|
108 |
+
// Handle any advanced option changes
|
109 |
+
// TODO
|
110 |
+
hmbkp_constant_changes();
|
111 |
|
112 |
}
|
113 |
+
add_action( 'admin_init', 'hmbkp_init' );
|
114 |
|
115 |
// Load the admin menu
|
116 |
+
require_once( HMBKP_PLUGIN_PATH . '/admin/menu.php' );
|
117 |
+
require_once( HMBKP_PLUGIN_PATH . '/admin/actions.php' );
|
118 |
|
119 |
// Load hm-backup
|
120 |
if ( ! class_exists( 'HM_Backup' ) )
|
121 |
require_once( HMBKP_PLUGIN_PATH . '/hm-backup/hm-backup.php' );
|
122 |
|
123 |
+
// Load the schedules
|
124 |
+
require_once( HMBKP_PLUGIN_PATH . '/classes/schedule.php' );
|
125 |
+
require_once( HMBKP_PLUGIN_PATH . '/classes/schedules.php' );
|
126 |
+
|
127 |
// Load the core functions
|
128 |
+
require_once( HMBKP_PLUGIN_PATH . '/functions/core.php' );
|
129 |
+
require_once( HMBKP_PLUGIN_PATH . '/functions/interface.php' );
|
130 |
+
|
131 |
+
// Load Services
|
132 |
+
require_once( HMBKP_PLUGIN_PATH . '/classes/services.php' );
|
133 |
+
|
134 |
+
// Load the email service
|
135 |
+
require_once( HMBKP_PLUGIN_PATH . '/classes/email.php' );
|
136 |
|
137 |
// Load the wp cli command
|
138 |
if ( defined( 'WP_CLI' ) && WP_CLI )
|
139 |
+
include( HMBKP_PLUGIN_PATH . '/classes/wp-cli.php' );
|
140 |
|
141 |
+
// Set the tmp directory to the backup path
|
142 |
if ( ! defined( 'PCLZIP_TEMPORARY_DIR' ) )
|
143 |
define( 'PCLZIP_TEMPORARY_DIR', trailingslashit( hmbkp_path() ) );
|
144 |
|
145 |
+
// Hook in the activation and deactivation actions
|
146 |
add_action( 'activate_' . HMBKP_PLUGIN_SLUG . '/plugin.php', 'hmbkp_activate' );
|
147 |
add_action( 'deactivate_' . HMBKP_PLUGIN_SLUG . '/plugin.php', 'hmbkp_deactivate' );
|
|
|
|
|
|
|
|
readme.txt
CHANGED
@@ -1,33 +1,35 @@
|
|
1 |
=== BackUpWordPress ===
|
2 |
-
Contributors: humanmade, joehoyle, mattheu, tcrsavage, willmot
|
3 |
Tags: back up, backup, backups, database, zip, db, files, archive, wp-cli, humanmade
|
4 |
-
Requires at least: 3.
|
5 |
-
Tested up to: 3.4.
|
6 |
-
Stable tag:
|
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
|
13 |
|
14 |
= Features =
|
15 |
|
|
|
16 |
* Super simple to use, no setup required.
|
17 |
* Uses `zip` and `mysqldump` for faster back ups if they are available.
|
18 |
* Works in low memory, "shared host" environments.
|
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 |
-
*
|
25 |
|
26 |
= Help develop this plugin =
|
27 |
|
28 |
-
The BackUpWordPress plugin is hosted
|
29 |
|
30 |
-
|
|
|
|
|
31 |
|
32 |
== Installation ==
|
33 |
|
@@ -85,7 +87,7 @@ If you have tried all these then feel free to contact support.
|
|
85 |
|
86 |
The script to be entered into the Heart Internet cPanel is: `/usr/bin/php5 /home/sites/yourdomain.com/public_html/wp-cron.php` (note the space between php5 and the location of the file). The file `wp-cron.php` `chmod` must be set to `711`.
|
87 |
|
88 |
-
**Further Support &
|
89 |
|
90 |
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>
|
91 |
|
@@ -95,10 +97,24 @@ You can also tweet <a href="http://twitter.com/humanmadeltd">@humanmadeltd</a> o
|
|
95 |
|
96 |
== Screenshots ==
|
97 |
|
98 |
-
1.
|
|
|
|
|
99 |
|
100 |
== Changelog ==
|
101 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
102 |
#### 1.6.9
|
103 |
|
104 |
* Updated and improved translations across the board - props @elektronikLexikon.
|
@@ -349,8 +365,8 @@ Fix some silly 1.0 bugs
|
|
349 |
|
350 |
#### 1.0
|
351 |
|
352 |
-
1.0 represents a total rewrite & rethink of the BackUpWordPress plugin with a focus on making it "Just Work". The management and development of the plugin has been taken over by [
|
353 |
|
354 |
#### Previous
|
355 |
|
356 |
-
Version 0.4.5 and previous were developed by [wpdprx](http://profiles.wordpress.org/users/wpdprx/)
|
1 |
=== BackUpWordPress ===
|
2 |
+
Contributors: humanmade, joehoyle, mattheu, tcrsavage, willmot, cuvelier
|
3 |
Tags: back up, backup, backups, database, zip, db, files, archive, wp-cli, humanmade
|
4 |
+
Requires at least: 3.3.3
|
5 |
+
Tested up to: 3.4.2
|
6 |
+
Stable tag: 2.0.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 on a schedule that suits you.
|
13 |
|
14 |
= Features =
|
15 |
|
16 |
+
* Manage multiple schedules.
|
17 |
* Super simple to use, no setup required.
|
18 |
* Uses `zip` and `mysqldump` for faster back ups if they are available.
|
19 |
* Works in low memory, "shared host" environments.
|
20 |
* Option to have each backup file emailed to you.
|
21 |
* Works on Linux & Windows Server.
|
22 |
* Exclude files and folders from your back ups.
|
|
|
23 |
* Good support should you need help.
|
24 |
+
* Translations for Spanish, German, Chinese, Romanian, Russian, Serbian, Lithuanian, Italian, Czech, Dutch, French, Basque.
|
25 |
|
26 |
= Help develop this plugin =
|
27 |
|
28 |
+
The BackUpWordPress plugin is hosted GitHub, if you want to help out with development or testing then head over to https://github.com/humanmade/backupwordpress/.
|
29 |
|
30 |
+
= Translations =
|
31 |
+
|
32 |
+
We'd also love help translating the plugin into more languages, if you can help then please contact support@hmn.md or visit http://translate.hmn.md/.
|
33 |
|
34 |
== Installation ==
|
35 |
|
87 |
|
88 |
The script to be entered into the Heart Internet cPanel is: `/usr/bin/php5 /home/sites/yourdomain.com/public_html/wp-cron.php` (note the space between php5 and the location of the file). The file `wp-cron.php` `chmod` must be set to `711`.
|
89 |
|
90 |
+
**Further Support & Feedback**
|
91 |
|
92 |
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>
|
93 |
|
97 |
|
98 |
== Screenshots ==
|
99 |
|
100 |
+
1. Manage multiple schedules.
|
101 |
+
2. Choose your schedule, backup type, number of backups to keep and whether to recieve a notification email.
|
102 |
+
3. Easily manage exclude rules and see exactly which files are included and excluded from your backup.
|
103 |
|
104 |
== Changelog ==
|
105 |
|
106 |
+
#### 2.0.1
|
107 |
+
|
108 |
+
* Fix fatal error on PHP 5.2.
|
109 |
+
|
110 |
+
#### 2.0
|
111 |
+
|
112 |
+
* Ability to have multiple schedules with separate settings & excludes per schedule.
|
113 |
+
* Ability to manage exclude rules and see exactly which files are included and excluded.
|
114 |
+
* Fix an issue with sites with an `open_basedir` restriction.
|
115 |
+
* Backups should now be much more reliable in low memory environments.
|
116 |
+
* Lots of other minor improvements and bug fixes.
|
117 |
+
|
118 |
#### 1.6.9
|
119 |
|
120 |
* Updated and improved translations across the board - props @elektronikLexikon.
|
365 |
|
366 |
#### 1.0
|
367 |
|
368 |
+
1.0 represents a total rewrite & rethink of the BackUpWordPress plugin with a focus on making it "Just Work". The management and development of the plugin has been taken over by [Human Made Limited](http://hmn.md) the chaps behind [WP Remote](https://wpremote.com)
|
369 |
|
370 |
#### Previous
|
371 |
|
372 |
+
Version 0.4.5 and previous were developed by [wpdprx](http://profiles.wordpress.org/users/wpdprx/)
|
screenshot-1.png
DELETED
Binary file
|