Version Description
= After an upgrade from version 2 =
Please check all settings after the update:
- Dropbox authentication must be done again
- SugarSync authentication must be done again
- S3 Settings
- Google Storage is now in S3
- Check all your passwords
Download this release
Release Info
Developer | danielhuesken |
Plugin | BackWPup – WordPress Backup Plugin |
Version | 3.2.4 |
Comparing to | |
See all releases |
Code changes from version 3.2.3 to 3.2.4
- backwpup.php +1 -1
- inc/class-admin.php +3 -2
- inc/class-create-archive.php +14 -33
- inc/class-cron.php +2 -2
- inc/class-destination-dropbox.php +376 -291
- inc/class-destination-folder.php +0 -1
- inc/class-job.php +5 -6
- inc/class-jobtype-file.php +6 -2
- inc/class-jobtype-wpexp.php +7 -5
- inc/class-mysqldump.php +26 -2
- inc/class-page-editjob.php +2 -1
- inc/class-page-jobs.php +9 -3
- inc/class-page-settings.php +11 -4
- readme.txt +7 -1
backwpup.php
CHANGED
@@ -5,7 +5,7 @@
|
|
5 |
* Description: WordPress Backup Plugin
|
6 |
* Author: Inpsyde GmbH
|
7 |
* Author URI: http://inpsyde.com
|
8 |
-
* Version: 3.2.
|
9 |
* Text Domain: backwpup
|
10 |
* Domain Path: /languages/
|
11 |
* Network: true
|
5 |
* Description: WordPress Backup Plugin
|
6 |
* Author: Inpsyde GmbH
|
7 |
* Author URI: http://inpsyde.com
|
8 |
+
* Version: 3.2.4
|
9 |
* Text Domain: backwpup
|
10 |
* Domain Path: /languages/
|
11 |
* Network: true
|
inc/class-admin.php
CHANGED
@@ -393,8 +393,9 @@ final class BackWPup_Admin {
|
|
393 |
|
394 |
if ( isset( $_REQUEST[ 'page' ] ) && strstr( $_REQUEST[ 'page' ], 'backwpup' ) ) {
|
395 |
$admin_footer_text = '<a href="' . __( 'http://marketpress.com', 'backwpup' ) . '" class="mp_logo" title="' . __( 'MarketPress', 'backwpup' ) . '">' . __( 'MarketPress', 'backwpup' ) . '</a>';
|
396 |
-
if ( ! class_exists( 'BackWPup_Pro', FALSE ) )
|
397 |
-
$admin_footer_text .= sprintf( __( '<a class="backwpup-get-pro" href="%s">Get BackWPup Pro now.</a>', 'backwpup' ),
|
|
|
398 |
|
399 |
return $admin_footer_text . $default_text;
|
400 |
}
|
393 |
|
394 |
if ( isset( $_REQUEST[ 'page' ] ) && strstr( $_REQUEST[ 'page' ], 'backwpup' ) ) {
|
395 |
$admin_footer_text = '<a href="' . __( 'http://marketpress.com', 'backwpup' ) . '" class="mp_logo" title="' . __( 'MarketPress', 'backwpup' ) . '">' . __( 'MarketPress', 'backwpup' ) . '</a>';
|
396 |
+
if ( ! class_exists( 'BackWPup_Pro', FALSE ) ) {
|
397 |
+
$admin_footer_text .= sprintf( __( '<a class="backwpup-get-pro" href="%s">Get BackWPup Pro now.</a>', 'backwpup' ), translate( BackWPup::get_plugin_data( 'PluginURI' ), 'backwpup' ) );
|
398 |
+
}
|
399 |
|
400 |
return $admin_footer_text . $default_text;
|
401 |
}
|
inc/class-create-archive.php
CHANGED
@@ -44,13 +44,6 @@ class BackWPup_Create_Archive {
|
|
44 |
*/
|
45 |
private $pclzip_file_list = array();
|
46 |
|
47 |
-
/**
|
48 |
-
* Saved encoding will restored on __destruct
|
49 |
-
*
|
50 |
-
* @var string
|
51 |
-
*/
|
52 |
-
private $previous_encoding = '';
|
53 |
-
|
54 |
/**
|
55 |
* File cont off added files to handel somethings that depends on it
|
56 |
*
|
@@ -121,10 +114,6 @@ class BackWPup_Create_Archive {
|
|
121 |
}
|
122 |
if( $this->get_method() == 'PclZip' ) {
|
123 |
$this->method = 'PclZip';
|
124 |
-
if ( ini_get( 'mbstring.func_overload' ) && function_exists( 'mb_internal_encoding' ) ) {
|
125 |
-
$this->previous_encoding = mb_internal_encoding();
|
126 |
-
mb_internal_encoding( 'ISO-8859-1' );
|
127 |
-
}
|
128 |
if ( ! defined('PCLZIP_TEMPORARY_DIR') ) {
|
129 |
define( 'PCLZIP_TEMPORARY_DIR', BackWPup::get_plugin_data( 'TEMP' ) );
|
130 |
}
|
@@ -162,11 +151,6 @@ class BackWPup_Create_Archive {
|
|
162 |
*/
|
163 |
public function __destruct() {
|
164 |
|
165 |
-
//set encoding back
|
166 |
-
if ( ! empty( $this->previous_encoding ) ) {
|
167 |
-
mb_internal_encoding( $this->previous_encoding );
|
168 |
-
}
|
169 |
-
|
170 |
//close PclZip Class
|
171 |
if ( is_object( $this->pclzip ) ) {
|
172 |
if ( count( $this->pclzip_file_list ) > 0 ) {
|
@@ -255,23 +239,6 @@ class BackWPup_Create_Archive {
|
|
255 |
//remove reserved chars
|
256 |
$name_in_archive = str_replace( array( "?", "<", ">", ":", "%","\"", "*", "|", chr(0) ) , '', $name_in_archive );
|
257 |
|
258 |
-
//convert chars in archives
|
259 |
-
if ( function_exists( 'iconv' ) ) {
|
260 |
-
$charsets = array( 'UTF-8', 'ASCII',
|
261 |
-
'ISO-8859-1', 'ISO-8859-2', 'ISO-8859-3', 'ISO-8859-4', 'ISO-8859-5',
|
262 |
-
'ISO-8859-6', 'ISO-8859-7', 'ISO-8859-8', 'ISO-8859-9', 'ISO-8859-10',
|
263 |
-
'ISO-8859-13', 'ISO-8859-14', 'ISO-8859-15', 'ISO-8859-16',
|
264 |
-
'Windows-1251', 'Windows-1252', 'Windows-1254'
|
265 |
-
);
|
266 |
-
foreach ( $charsets as $charset ) {
|
267 |
-
$test = @iconv( $charset, 'UTF-8', $name_in_archive );
|
268 |
-
if ( $test ) {
|
269 |
-
$name_in_archive = $test;
|
270 |
-
break;
|
271 |
-
}
|
272 |
-
}
|
273 |
-
}
|
274 |
-
|
275 |
switch ( $this->get_method() ) {
|
276 |
case 'gz':
|
277 |
if ( $this->file_count > 0 ) {
|
@@ -308,9 +275,23 @@ class BackWPup_Create_Archive {
|
|
308 |
case 'Tar':
|
309 |
case 'TarGz':
|
310 |
case 'TarBz2':
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
311 |
return $this->tar_file( $file_name, $name_in_archive );
|
312 |
break;
|
313 |
case 'ZipArchive':
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
$file_size = filesize( $file_name );
|
315 |
if ( $file_size === FALSE ) {
|
316 |
return FALSE;
|
44 |
*/
|
45 |
private $pclzip_file_list = array();
|
46 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
/**
|
48 |
* File cont off added files to handel somethings that depends on it
|
49 |
*
|
114 |
}
|
115 |
if( $this->get_method() == 'PclZip' ) {
|
116 |
$this->method = 'PclZip';
|
|
|
|
|
|
|
|
|
117 |
if ( ! defined('PCLZIP_TEMPORARY_DIR') ) {
|
118 |
define( 'PCLZIP_TEMPORARY_DIR', BackWPup::get_plugin_data( 'TEMP' ) );
|
119 |
}
|
151 |
*/
|
152 |
public function __destruct() {
|
153 |
|
|
|
|
|
|
|
|
|
|
|
154 |
//close PclZip Class
|
155 |
if ( is_object( $this->pclzip ) ) {
|
156 |
if ( count( $this->pclzip_file_list ) > 0 ) {
|
239 |
//remove reserved chars
|
240 |
$name_in_archive = str_replace( array( "?", "<", ">", ":", "%","\"", "*", "|", chr(0) ) , '', $name_in_archive );
|
241 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
242 |
switch ( $this->get_method() ) {
|
243 |
case 'gz':
|
244 |
if ( $this->file_count > 0 ) {
|
275 |
case 'Tar':
|
276 |
case 'TarGz':
|
277 |
case 'TarBz2':
|
278 |
+
//convert chars for archives file names
|
279 |
+
if ( function_exists( 'iconv' ) && stristr( PHP_OS, 'win' ) !== false ) {
|
280 |
+
$test = @iconv( 'ISO-8859-1', 'UTF-8', $name_in_archive );
|
281 |
+
if ( $test ) {
|
282 |
+
$name_in_archive = $test;
|
283 |
+
}
|
284 |
+
}
|
285 |
return $this->tar_file( $file_name, $name_in_archive );
|
286 |
break;
|
287 |
case 'ZipArchive':
|
288 |
+
//convert chars for archives file names
|
289 |
+
if ( function_exists( 'iconv' ) && stristr( PHP_OS, 'win' ) === false ) {
|
290 |
+
$test = @iconv( 'UTF-8', 'CP437', $name_in_archive );
|
291 |
+
if ( $test ) {
|
292 |
+
$name_in_archive = $test;
|
293 |
+
}
|
294 |
+
}
|
295 |
$file_size = filesize( $file_name );
|
296 |
if ( $file_size === FALSE ) {
|
297 |
return FALSE;
|
inc/class-cron.php
CHANGED
@@ -138,8 +138,8 @@ class BackWPup_Cron {
|
|
138 |
nocache_headers();
|
139 |
|
140 |
//on test die for fast feedback
|
141 |
-
if ( $_GET[ 'backwpup_run' ]
|
142 |
-
die( '
|
143 |
}
|
144 |
|
145 |
// generate normal nonce
|
138 |
nocache_headers();
|
139 |
|
140 |
//on test die for fast feedback
|
141 |
+
if ( $_GET[ 'backwpup_run' ] === 'test' ) {
|
142 |
+
die( '' );
|
143 |
}
|
144 |
|
145 |
// generate normal nonce
|
inc/class-destination-dropbox.php
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
<?php
|
|
|
2 |
/**
|
3 |
* Documentation: https://www.dropbox.com/developers/reference/api
|
4 |
*/
|
@@ -7,14 +8,20 @@ class BackWPup_Destination_Dropbox extends BackWPup_Destinations {
|
|
7 |
/**
|
8 |
* @var $backwpup_job_object BackWPup_Job
|
9 |
*/
|
10 |
-
public static $backwpup_job_object =
|
11 |
|
12 |
/**
|
13 |
* @return array
|
14 |
*/
|
15 |
public function option_defaults() {
|
16 |
|
17 |
-
return array(
|
|
|
|
|
|
|
|
|
|
|
|
|
18 |
}
|
19 |
|
20 |
|
@@ -23,14 +30,18 @@ class BackWPup_Destination_Dropbox extends BackWPup_Destinations {
|
|
23 |
*/
|
24 |
public function edit_tab( $jobid ) {
|
25 |
|
26 |
-
if ( ! empty( $_GET[
|
27 |
//disable token on dropbox
|
28 |
try {
|
29 |
$dropbox = new BackWPup_Destination_Dropbox_API( BackWPup_Option::get( $jobid, 'dropboxroot' ) );
|
30 |
-
if ( BackWPup_Option::get( $jobid, 'dropboxsecret' ) )
|
31 |
-
$dropbox->setOAuthTokens( array(
|
32 |
-
|
|
|
|
|
|
|
33 |
$dropbox->setOAuthTokens( BackWPup_Option::get( $jobid, 'dropboxtoken' ) );
|
|
|
34 |
$dropbox->disable_access_token();
|
35 |
} catch ( Exception $e ) {
|
36 |
echo '<div id="message" class="error"><p>' . sprintf( __( 'Dropbox API: %s', 'backwpup' ), $e->getMessage() ) . '</p></div>';
|
@@ -40,122 +51,148 @@ class BackWPup_Destination_Dropbox extends BackWPup_Destinations {
|
|
40 |
BackWPup_Option::delete( $jobid, 'dropboxsecret' );
|
41 |
}
|
42 |
|
43 |
-
$dropbox
|
44 |
$dropbox_auth_url = $dropbox->oAuthAuthorize();
|
45 |
-
$dropbox
|
46 |
$sandbox_auth_url = $dropbox->oAuthAuthorize();
|
47 |
|
48 |
$dropboxtoken = BackWPup_Option::get( $jobid, 'dropboxtoken' );
|
49 |
?>
|
50 |
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
56 |
-
|
57 |
-
|
58 |
-
|
59 |
-
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
68 |
-
|
69 |
-
|
70 |
-
<
|
71 |
-
|
72 |
-
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
-
|
79 |
-
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
<
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
|
95 |
-
|
96 |
-
|
97 |
-
|
98 |
-
|
99 |
-
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
|
107 |
-
|
108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
109 |
<?php } else { ?>
|
110 |
-
|
111 |
-
|
112 |
-
|
|
|
|
|
113 |
<?php } ?>
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
|
118 |
-
|
119 |
}
|
120 |
|
121 |
/**
|
122 |
* @param $jobid
|
|
|
123 |
* @return string|void
|
124 |
*/
|
125 |
public function edit_form_post_save( $jobid ) {
|
126 |
|
127 |
// get auth
|
128 |
-
if ( ! empty( $_POST[
|
129 |
try {
|
130 |
-
$dropbox
|
131 |
-
$dropboxtoken = $dropbox->oAuthToken( $_POST[
|
132 |
BackWPup_Option::update( $jobid, 'dropboxtoken', $dropboxtoken );
|
133 |
BackWPup_Option::update( $jobid, 'dropboxroot', 'sandbox' );
|
134 |
} catch ( Exception $e ) {
|
135 |
-
BackWPup_Admin::message( 'DROPBOX: ' . $e->getMessage(),
|
136 |
}
|
137 |
}
|
138 |
|
139 |
-
if ( ! empty( $_POST[
|
140 |
try {
|
141 |
-
$dropbox
|
142 |
-
$dropboxtoken = $dropbox->oAuthToken( $_POST[
|
143 |
BackWPup_Option::update( $jobid, 'dropboxtoken', $dropboxtoken );
|
144 |
BackWPup_Option::update( $jobid, 'dropboxroot', 'dropbox' );
|
145 |
} catch ( Exception $e ) {
|
146 |
-
BackWPup_Admin::message( 'DROPBOX: ' . $e->getMessage(),
|
147 |
}
|
148 |
}
|
149 |
|
150 |
-
BackWPup_Option::update( $jobid, 'dropboxsyncnodelete', ( isset( $_POST[
|
151 |
-
BackWPup_Option::update( $jobid, 'dropboxmaxbackups', isset( $_POST[
|
152 |
|
153 |
-
$_POST[
|
154 |
-
if ( substr( $_POST[
|
155 |
-
$_POST[
|
156 |
-
|
157 |
-
|
158 |
-
|
|
|
|
|
159 |
|
160 |
}
|
161 |
|
@@ -174,13 +211,13 @@ class BackWPup_Destination_Dropbox extends BackWPup_Destinations {
|
|
174 |
$dropbox->fileopsDelete( $backupfile );
|
175 |
//update file list
|
176 |
foreach ( $files as $key => $file ) {
|
177 |
-
if ( is_array( $file ) && $file[
|
178 |
unset( $files[ $key ] );
|
|
|
179 |
}
|
180 |
unset( $dropbox );
|
181 |
-
}
|
182 |
-
|
183 |
-
BackWPup_Admin::message( 'DROPBOX: ' . $e->getMessage(), TRUE );
|
184 |
}
|
185 |
|
186 |
set_site_transient( 'backwpup_' . strtolower( $jobdest ), $files, 3600 * 24 * 7 );
|
@@ -196,17 +233,18 @@ class BackWPup_Destination_Dropbox extends BackWPup_Destinations {
|
|
196 |
$dropbox = new BackWPup_Destination_Dropbox_API( BackWPup_Option::get( $jobid, 'dropboxroot' ) );
|
197 |
$dropbox->setOAuthTokens( BackWPup_Option::get( $jobid, 'dropboxtoken' ) );
|
198 |
$media = $dropbox->media( $get_file );
|
199 |
-
if ( ! empty( $media[
|
200 |
-
header( "Location: " . $media[
|
|
|
201 |
die();
|
202 |
-
}
|
203 |
-
catch ( Exception $e ) {
|
204 |
die( $e->getMessage() );
|
205 |
}
|
206 |
}
|
207 |
|
208 |
/**
|
209 |
* @param $jobdest
|
|
|
210 |
* @return mixed
|
211 |
*/
|
212 |
public function file_get_list( $jobdest ) {
|
@@ -215,44 +253,50 @@ class BackWPup_Destination_Dropbox extends BackWPup_Destinations {
|
|
215 |
|
216 |
/**
|
217 |
* @param $job_object
|
|
|
218 |
* @return bool
|
219 |
*/
|
220 |
public function job_run_archive( BackWPup_Job $job_object ) {
|
221 |
|
222 |
$job_object->substeps_todo = 2 + $job_object->backup_filesize;
|
223 |
-
if ( $job_object->steps_data[ $job_object->step_working ]['SAVE_STEP_TRY'] != $job_object->steps_data[ $job_object->step_working ][
|
224 |
-
$job_object->log( sprintf( __( '%d. Try to send backup file to Dropbox …', 'backwpup' ), $job_object->steps_data[ $job_object->step_working ][
|
|
|
225 |
|
226 |
try {
|
227 |
-
$dropbox = new BackWPup_Destination_Dropbox_API( $job_object->job[
|
228 |
// cahnge oauth1 to oauth2 token
|
229 |
-
if ( ! empty( $job_object->job[
|
230 |
-
$dropbox->setOAuthTokens( array(
|
231 |
-
|
232 |
-
|
233 |
-
|
|
|
|
|
|
|
234 |
}
|
235 |
// set the tokens
|
236 |
-
$dropbox->setOAuthTokens( $job_object->job[
|
237 |
|
238 |
//get account info
|
239 |
-
if ( $job_object->steps_data[ $job_object->step_working ]['SAVE_STEP_TRY'] != $job_object->steps_data[ $job_object->step_working ][
|
240 |
$info = $dropbox->accountInfo();
|
241 |
-
if ( ! empty( $info[
|
242 |
if ( $job_object->is_debug() ) {
|
243 |
-
$user = $info[
|
244 |
} else {
|
245 |
-
$user = $info[
|
246 |
}
|
247 |
$job_object->log( sprintf( __( 'Authenticated with Dropbox of user: %s', 'backwpup' ), $user ) );
|
248 |
//Quota
|
249 |
if ( $job_object->is_debug() ) {
|
250 |
-
$dropboxfreespase = $info[
|
251 |
$job_object->log( sprintf( __( '%s available on your Dropbox', 'backwpup' ), size_format( $dropboxfreespase, 2 ) ) );
|
252 |
}
|
253 |
} else {
|
254 |
$job_object->log( __( 'Not Authenticated with Dropbox!', 'backwpup' ), E_USER_ERROR );
|
255 |
-
|
|
|
256 |
}
|
257 |
$job_object->log( __( 'Uploading to Dropbox …', 'backwpup' ) );
|
258 |
}
|
@@ -261,24 +305,25 @@ class BackWPup_Destination_Dropbox extends BackWPup_Destinations {
|
|
261 |
self::$backwpup_job_object = &$job_object;
|
262 |
|
263 |
if ( $job_object->substeps_done < $job_object->backup_filesize ) { //only if upload not complete
|
264 |
-
$response = $dropbox->upload( $job_object->backup_folder . $job_object->backup_file, $job_object->job[
|
265 |
-
if ( $response[
|
266 |
-
if ( ! empty( $job_object->job[
|
267 |
-
BackWPup_Option::update(
|
|
|
268 |
$job_object->substeps_done = 1 + $job_object->backup_filesize;
|
269 |
-
$job_object->log( sprintf( __( 'Backup transferred to %s', 'backwpup' ), 'https://
|
270 |
-
}
|
271 |
-
|
272 |
-
if ( $response[ 'bytes' ] != $job_object->backup_filesize )
|
273 |
$job_object->log( __( 'Uploaded file size and local file size don\'t match.', 'backwpup' ), E_USER_ERROR );
|
274 |
-
else
|
275 |
$job_object->log(
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
|
|
280 |
|
281 |
-
return
|
282 |
}
|
283 |
}
|
284 |
|
@@ -286,68 +331,72 @@ class BackWPup_Destination_Dropbox extends BackWPup_Destinations {
|
|
286 |
$backupfilelist = array();
|
287 |
$filecounter = 0;
|
288 |
$files = array();
|
289 |
-
$metadata = $dropbox->metadata( $job_object->job[
|
290 |
if ( is_array( $metadata ) ) {
|
291 |
-
foreach ( $metadata[
|
292 |
-
if ( $data[
|
293 |
-
$file = basename( $data[
|
294 |
if ( $job_object->is_backup_archive( $file ) ) {
|
295 |
-
$backupfilelist[ strtotime( $data[
|
296 |
}
|
297 |
-
$files[ $filecounter ][
|
298 |
-
$files[ $filecounter ][
|
299 |
-
$files[ $filecounter ][
|
300 |
-
$files[ $filecounter ][
|
301 |
-
$files[ $filecounter ][
|
302 |
-
$files[ $filecounter ][
|
303 |
$filecounter ++;
|
304 |
}
|
305 |
}
|
306 |
}
|
307 |
-
if ( $job_object->job[
|
308 |
-
if ( count( $backupfilelist ) > $job_object->job[
|
309 |
ksort( $backupfilelist );
|
310 |
$numdeltefiles = 0;
|
311 |
while ( $file = array_shift( $backupfilelist ) ) {
|
312 |
-
if ( count( $backupfilelist ) < $job_object->job[
|
313 |
break;
|
314 |
-
|
315 |
-
|
|
|
316 |
foreach ( $files as $key => $filedata ) {
|
317 |
-
if ( $filedata[
|
318 |
unset( $files[ $key ] );
|
|
|
319 |
}
|
320 |
$numdeltefiles ++;
|
321 |
-
}
|
322 |
-
else
|
323 |
$job_object->log( sprintf( __( 'Error while deleting file from Dropbox: %s', 'backwpup' ), $file ), E_USER_ERROR );
|
|
|
324 |
}
|
325 |
-
if ( $numdeltefiles > 0 )
|
326 |
$job_object->log( sprintf( _n( 'One file deleted from Dropbox', '%d files deleted on Dropbox', $numdeltefiles, 'backwpup' ), $numdeltefiles ), E_USER_NOTICE );
|
|
|
327 |
}
|
328 |
}
|
329 |
-
set_site_transient( 'backwpup_' . $job_object->job[
|
330 |
-
}
|
331 |
-
catch ( Exception $e ) {
|
332 |
$job_object->log( E_USER_ERROR, sprintf( __( 'Dropbox API: %s', 'backwpup' ), $e->getMessage() ), $e->getFile(), $e->getLine() );
|
333 |
|
334 |
-
return
|
335 |
}
|
336 |
$job_object->substeps_done ++;
|
337 |
|
338 |
-
return
|
339 |
}
|
340 |
|
341 |
/**
|
342 |
* @param $job_settings
|
|
|
343 |
* @return bool
|
344 |
*/
|
345 |
public function can_run( array $job_settings ) {
|
346 |
|
347 |
-
if ( empty( $job_settings[
|
348 |
-
return
|
|
|
349 |
|
350 |
-
return
|
351 |
}
|
352 |
|
353 |
}
|
@@ -361,17 +410,17 @@ final class BackWPup_Destination_Dropbox_API {
|
|
361 |
/**
|
362 |
*
|
363 |
*/
|
364 |
-
const API_URL
|
365 |
|
366 |
/**
|
367 |
*
|
368 |
*/
|
369 |
-
const API_CONTENT_URL = 'https://
|
370 |
|
371 |
/**
|
372 |
*
|
373 |
*/
|
374 |
-
const API_WWW_URL
|
375 |
|
376 |
/**
|
377 |
*
|
@@ -402,41 +451,43 @@ final class BackWPup_Destination_Dropbox_API {
|
|
402 |
private $oauth_token = '';
|
403 |
|
404 |
|
405 |
-
|
406 |
/**
|
407 |
* @param string $boxtype
|
|
|
408 |
* @throws BackWPup_Destination_Dropbox_API_Exception
|
409 |
*/
|
410 |
public function __construct( $boxtype = 'dropbox' ) {
|
411 |
|
412 |
if ( $boxtype == 'dropbox' ) {
|
413 |
-
$this->oauth_app_key
|
414 |
$this->oauth_app_secret = BackWPup_Encryption::decrypt( get_site_option( 'backwpup_cfg_dropboxappsecret', base64_decode( "OWV2bDR5MHJvZ2RlYmx1" ) ) );
|
415 |
$this->root = 'dropbox';
|
416 |
-
}
|
417 |
-
|
418 |
-
$this->oauth_app_key = get_site_option( 'backwpup_cfg_dropboxsandboxappkey', base64_decode( "cHVrZmp1a3JoZHR5OTFk" ) );
|
419 |
$this->oauth_app_secret = BackWPup_Encryption::decrypt( get_site_option( 'backwpup_cfg_dropboxsandboxappsecret', base64_decode( "eGNoYzhxdTk5eHE0eWdq" ) ) );
|
420 |
$this->root = 'sandbox';
|
421 |
}
|
422 |
|
423 |
-
if ( empty( $this->oauth_app_key ) || empty( $this->oauth_app_secret ) )
|
424 |
throw new BackWPup_Destination_Dropbox_API_Exception( "No App key or App Secret specified." );
|
|
|
425 |
}
|
426 |
|
427 |
/**
|
428 |
* @param $token
|
|
|
429 |
* @throws BackWPup_Destination_Dropbox_API_Exception
|
430 |
*/
|
431 |
public function setOAuthTokens( $token ) {
|
432 |
|
433 |
-
if ( empty( $token[
|
434 |
throw new BackWPup_Destination_Dropbox_API_Exception( "No oAuth token specified." );
|
|
|
435 |
|
436 |
$this->oauth_token = $token;
|
437 |
}
|
438 |
|
439 |
-
public function token_from_oauth1(
|
440 |
|
441 |
$url = self::API_URL . self::API_VERSION_URL . 'oauth2/token_from_oauth1';
|
442 |
|
@@ -463,11 +514,12 @@ final class BackWPup_Destination_Dropbox_API {
|
|
463 |
/**
|
464 |
* @param $file
|
465 |
* @param string $path
|
466 |
-
* @param bool
|
|
|
467 |
* @return array|mixed|string
|
468 |
* @throws BackWPup_Destination_Dropbox_API_Exception
|
469 |
*/
|
470 |
-
public function upload( $file, $path = '', $overwrite =
|
471 |
|
472 |
$file = str_replace( "\\", "/", $file );
|
473 |
|
@@ -476,10 +528,9 @@ final class BackWPup_Destination_Dropbox_API {
|
|
476 |
}
|
477 |
|
478 |
if ( filesize( $file ) < 5242880 ) { //chunk transfer on bigger uploads
|
479 |
-
$url
|
480 |
-
$output
|
481 |
-
}
|
482 |
-
else {
|
483 |
$output = $this->chunked_upload( $file, $path, $overwrite );
|
484 |
}
|
485 |
|
@@ -489,11 +540,12 @@ final class BackWPup_Destination_Dropbox_API {
|
|
489 |
/**
|
490 |
* @param $file
|
491 |
* @param string $path
|
492 |
-
* @param bool
|
|
|
493 |
* @return array|mixed|string
|
494 |
* @throws BackWPup_Destination_Dropbox_API_Exception
|
495 |
*/
|
496 |
-
public function chunked_upload( $file, $path = '', $overwrite =
|
497 |
|
498 |
$backwpup_job_object = BackWPup_Destination_Dropbox::$backwpup_job_object;
|
499 |
|
@@ -510,33 +562,36 @@ final class BackWPup_Destination_Dropbox_API {
|
|
510 |
throw new BackWPup_Destination_Dropbox_API_Exception( "Can not open source file for transfer." );
|
511 |
}
|
512 |
|
513 |
-
if ( ! isset( $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ][
|
514 |
-
$backwpup_job_object->steps_data[ $backwpup_job_object->step_working ][
|
515 |
}
|
516 |
-
if ( ! isset( $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ][
|
517 |
-
$backwpup_job_object->steps_data[ $backwpup_job_object->step_working ][
|
518 |
}
|
519 |
|
520 |
//seek to current position
|
521 |
-
if ( $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ][
|
522 |
-
fseek( $file_handel, $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ][
|
523 |
}
|
524 |
|
525 |
while ( $data = fread( $file_handel, $chunk_size ) ) {
|
526 |
-
$chunk_upload_start = microtime(
|
527 |
-
$url
|
528 |
-
$output
|
529 |
-
|
|
|
|
|
|
|
530 |
//args for next chunk
|
531 |
-
$backwpup_job_object->steps_data[ $backwpup_job_object->step_working ][
|
532 |
-
$backwpup_job_object->steps_data[ $backwpup_job_object->step_working ][
|
533 |
-
if ( $backwpup_job_object->job[
|
534 |
-
$backwpup_job_object->substeps_done = $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ][
|
535 |
if ( strlen( $data ) == $chunk_size ) {
|
536 |
$time_remaining = $backwpup_job_object->do_restart_time();
|
537 |
//calc next chunk
|
538 |
if ( $time_remaining < $chunk_upload_time ) {
|
539 |
-
$chunk_size = floor
|
540 |
if ( $chunk_size < 0 ) {
|
541 |
$chunk_size = 1024;
|
542 |
}
|
@@ -548,52 +603,64 @@ final class BackWPup_Destination_Dropbox_API {
|
|
548 |
}
|
549 |
$backwpup_job_object->update_working_data();
|
550 |
//correct position
|
551 |
-
fseek( $file_handel, $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ][
|
552 |
}
|
553 |
|
554 |
fclose( $file_handel );
|
555 |
|
556 |
$url = self::API_CONTENT_URL . self::API_VERSION_URL . 'commit_chunked_upload/' . $this->root . '/' . $this->encode_path( $path );
|
557 |
|
558 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
559 |
}
|
560 |
|
561 |
/**
|
562 |
* @param $path
|
563 |
* @param bool $echo
|
|
|
564 |
* @return string
|
565 |
*/
|
566 |
-
public function download( $path, $echo =
|
567 |
|
568 |
-
$url = self::API_CONTENT_URL . self::API_VERSION_URL . 'files/' . $this->root . '/' .
|
569 |
-
if ( ! $echo )
|
570 |
return $this->request( $url );
|
571 |
-
else {
|
572 |
-
$this->request( $url,
|
|
|
573 |
return '';
|
574 |
}
|
575 |
}
|
576 |
|
577 |
/**
|
578 |
* @param string $path
|
579 |
-
* @param bool
|
580 |
-
* @param int
|
581 |
* @param string $hash
|
|
|
582 |
* @return array|mixed|string
|
583 |
*/
|
584 |
-
public function metadata( $path = '', $listContents =
|
585 |
|
586 |
$url = self::API_URL . self::API_VERSION_URL . 'metadata/' . $this->root . '/' . $this->encode_path( $path );
|
587 |
|
588 |
return $this->request( $url, array(
|
589 |
-
|
590 |
-
|
591 |
-
|
592 |
-
|
593 |
}
|
594 |
|
595 |
/**
|
596 |
* @param string $path
|
|
|
597 |
* @return array|mixed|string
|
598 |
*/
|
599 |
public function media( $path = '' ) {
|
@@ -605,6 +672,7 @@ final class BackWPup_Destination_Dropbox_API {
|
|
605 |
|
606 |
/**
|
607 |
* @param $path
|
|
|
608 |
* @return array|mixed|string
|
609 |
*/
|
610 |
public function fileopsDelete( $path ) {
|
@@ -612,12 +680,12 @@ final class BackWPup_Destination_Dropbox_API {
|
|
612 |
$url = self::API_URL . self::API_VERSION_URL . 'fileops/delete';
|
613 |
|
614 |
return $this->request( $url, array(
|
615 |
-
|
616 |
-
|
617 |
-
|
618 |
}
|
619 |
|
620 |
-
public function oAuthAuthorize(
|
621 |
|
622 |
return self::API_WWW_URL . self::API_VERSION_URL . 'oauth2/authorize?response_type=code&client_id=' . $this->oauth_app_key;
|
623 |
}
|
@@ -628,113 +696,115 @@ final class BackWPup_Destination_Dropbox_API {
|
|
628 |
$url = self::API_URL . self::API_VERSION_URL . 'oauth2/token';
|
629 |
|
630 |
return $this->request( $url, array(
|
631 |
-
|
632 |
-
|
633 |
-
|
634 |
-
|
635 |
-
|
636 |
|
637 |
}
|
638 |
|
639 |
|
640 |
/**
|
641 |
* @param $url
|
642 |
-
* @param array
|
643 |
* @param string $method
|
644 |
* @param string $data
|
645 |
-
* @param bool
|
646 |
*
|
647 |
* @throws BackWPup_Destination_Dropbox_API_Exception
|
648 |
* @internal param null $file
|
649 |
* @return array|mixed|string
|
650 |
*/
|
651 |
-
private function request( $url, $args = array(), $method = 'GET', $data = '', $echo =
|
652 |
|
653 |
/* Header*/
|
654 |
// oAuth 2
|
655 |
-
if ( ! empty( $this->oauth_token[
|
656 |
-
$headers[
|
657 |
-
// oAuth 1
|
658 |
-
elseif ( ! empty( $this->oauth_token[
|
659 |
-
$headers[
|
|
|
660 |
|
661 |
-
$headers[
|
662 |
|
663 |
/* Build cURL Request */
|
664 |
$ch = curl_init();
|
665 |
if ( $method == 'POST' ) {
|
666 |
-
curl_setopt( $ch, CURLOPT_POST,
|
667 |
curl_setopt( $ch, CURLOPT_POSTFIELDS, $args );
|
668 |
curl_setopt( $ch, CURLOPT_URL, $url );
|
669 |
-
}
|
670 |
-
elseif ( $method == 'PUT' ) {
|
671 |
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'PUT' );
|
672 |
curl_setopt( $ch, CURLOPT_POSTFIELDS, $data );
|
673 |
-
$headers[
|
674 |
-
$args
|
675 |
curl_setopt( $ch, CURLOPT_URL, $url . $args );
|
676 |
-
}
|
677 |
-
|
678 |
-
curl_setopt( $ch, CURLOPT_BINARYTRANSFER, TRUE );
|
679 |
$args = ( is_array( $args ) ) ? '?' . http_build_query( $args, '', '&' ) : $args;
|
680 |
curl_setopt( $ch, CURLOPT_URL, $url . $args );
|
681 |
}
|
682 |
curl_setopt( $ch, CURLOPT_USERAGENT, BackWPup::get_plugin_data( 'User-Agent' ) );
|
683 |
-
curl_setopt( $ch, CURLOPT_RETURNTRANSFER,
|
684 |
if ( BackWPup::get_plugin_data( 'cacert' ) ) {
|
685 |
curl_setopt( $ch, CURLOPT_SSLVERSION, 1 );
|
686 |
-
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER,
|
687 |
$curl_version = curl_version();
|
688 |
-
if ( strstr( $curl_version[
|
689 |
curl_setopt( $ch, CURLOPT_SSL_CIPHER_LIST,
|
690 |
-
|
691 |
-
|
692 |
-
|
693 |
-
|
694 |
-
|
695 |
-
|
696 |
-
|
697 |
-
|
698 |
-
|
699 |
-
|
700 |
-
|
701 |
-
|
702 |
-
|
703 |
-
|
704 |
-
|
705 |
-
|
706 |
-
|
707 |
-
|
708 |
-
|
709 |
);
|
710 |
}
|
711 |
-
if ( defined( 'CURLOPT_PROTOCOLS' ) )
|
712 |
curl_setopt( $ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS );
|
713 |
-
|
|
|
714 |
curl_setopt( $ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS );
|
|
|
715 |
curl_setopt( $ch, CURLOPT_CAINFO, BackWPup::get_plugin_data( 'cacert' ) );
|
716 |
curl_setopt( $ch, CURLOPT_CAPATH, dirname( BackWPup::get_plugin_data( 'cacert' ) ) );
|
717 |
} else {
|
718 |
-
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER,
|
719 |
}
|
720 |
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
|
721 |
$output = '';
|
722 |
if ( $echo ) {
|
723 |
echo curl_exec( $ch );
|
724 |
-
}
|
725 |
-
|
726 |
-
curl_setopt( $ch, CURLOPT_HEADER, TRUE );
|
727 |
if ( 0 == curl_errno( $ch ) ) {
|
728 |
$responce = explode( "\r\n\r\n", curl_exec( $ch ), 2 );
|
729 |
-
if ( ! empty( $responce[
|
730 |
-
$output = json_decode( $responce[
|
|
|
731 |
}
|
732 |
}
|
733 |
$status = curl_getinfo( $ch );
|
734 |
-
if ( $status[
|
735 |
$wait = 0;
|
736 |
-
if ( preg_match( "/retry-after:(.*?)\r/i", $responce[
|
737 |
-
$wait = trim( $matches[
|
|
|
738 |
//only wait if we get a retry-after header.
|
739 |
if ( ! empty( $wait ) ) {
|
740 |
trigger_error( sprintf( '(503) Your app is making too many requests and is being rate limited. Error 503 can be triggered on a per-app or per-user basis. Wait for %d seconds.', $wait ), E_USER_WARNING );
|
@@ -742,42 +812,57 @@ final class BackWPup_Destination_Dropbox_API {
|
|
742 |
} else {
|
743 |
throw new BackWPup_Destination_Dropbox_API_Exception( '(503) This indicates a transient server error.' );
|
744 |
}
|
|
|
745 |
//redo request
|
746 |
return $this->request( $url, $args, $method, $data, $echo );
|
747 |
-
}
|
748 |
-
|
749 |
-
trigger_error( '(' . $status[ 'http_code' ] . ') False offset will corrected', E_USER_NOTICE );
|
750 |
-
return $output;
|
751 |
-
}
|
752 |
-
elseif ( $status[ 'http_code' ] == 404 && ! empty( $output[ 'error' ] )) {
|
753 |
-
trigger_error( '(' . $status[ 'http_code' ] . ') ' . $output[ 'error' ], E_USER_WARNING );
|
754 |
|
755 |
-
return
|
756 |
-
}
|
757 |
-
|
758 |
-
|
759 |
-
|
760 |
-
|
761 |
-
|
762 |
-
|
763 |
-
elseif ( $
|
764 |
-
|
765 |
-
elseif (
|
766 |
-
|
767 |
-
elseif ( $status[
|
768 |
-
|
769 |
-
elseif ( $status[
|
770 |
-
|
771 |
-
elseif ( $status[
|
772 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
773 |
throw new BackWPup_Destination_Dropbox_API_Exception( $message );
|
774 |
-
}
|
775 |
-
else {
|
776 |
curl_close( $ch );
|
777 |
-
if ( ! is_array( $output ) )
|
778 |
-
return $responce[
|
779 |
-
else
|
780 |
return $output;
|
|
|
781 |
}
|
782 |
}
|
783 |
|
1 |
<?php
|
2 |
+
|
3 |
/**
|
4 |
* Documentation: https://www.dropbox.com/developers/reference/api
|
5 |
*/
|
8 |
/**
|
9 |
* @var $backwpup_job_object BackWPup_Job
|
10 |
*/
|
11 |
+
public static $backwpup_job_object = null;
|
12 |
|
13 |
/**
|
14 |
* @return array
|
15 |
*/
|
16 |
public function option_defaults() {
|
17 |
|
18 |
+
return array(
|
19 |
+
'dropboxtoken' => array(),
|
20 |
+
'dropboxroot' => 'sandbox',
|
21 |
+
'dropboxmaxbackups' => 15,
|
22 |
+
'dropboxsyncnodelete' => true,
|
23 |
+
'dropboxdir' => trailingslashit( sanitize_file_name( get_bloginfo( 'name' ) ) )
|
24 |
+
);
|
25 |
}
|
26 |
|
27 |
|
30 |
*/
|
31 |
public function edit_tab( $jobid ) {
|
32 |
|
33 |
+
if ( ! empty( $_GET['deleteauth'] ) && $_GET['deleteauth'] == 1 ) {
|
34 |
//disable token on dropbox
|
35 |
try {
|
36 |
$dropbox = new BackWPup_Destination_Dropbox_API( BackWPup_Option::get( $jobid, 'dropboxroot' ) );
|
37 |
+
if ( BackWPup_Option::get( $jobid, 'dropboxsecret' ) ) {
|
38 |
+
$dropbox->setOAuthTokens( array(
|
39 |
+
'access_token' => BackWPup_Option::get( $jobid, 'dropboxtoken' ),
|
40 |
+
'oauth_token_secret' => BackWPup_Encryption::decrypt( BackWPup_Option::get( $jobid, 'dropboxsecret' ) )
|
41 |
+
) );
|
42 |
+
} else {
|
43 |
$dropbox->setOAuthTokens( BackWPup_Option::get( $jobid, 'dropboxtoken' ) );
|
44 |
+
}
|
45 |
$dropbox->disable_access_token();
|
46 |
} catch ( Exception $e ) {
|
47 |
echo '<div id="message" class="error"><p>' . sprintf( __( 'Dropbox API: %s', 'backwpup' ), $e->getMessage() ) . '</p></div>';
|
51 |
BackWPup_Option::delete( $jobid, 'dropboxsecret' );
|
52 |
}
|
53 |
|
54 |
+
$dropbox = new BackWPup_Destination_Dropbox_API( 'dropbox' );
|
55 |
$dropbox_auth_url = $dropbox->oAuthAuthorize();
|
56 |
+
$dropbox = new BackWPup_Destination_Dropbox_API( 'sandbox' );
|
57 |
$sandbox_auth_url = $dropbox->oAuthAuthorize();
|
58 |
|
59 |
$dropboxtoken = BackWPup_Option::get( $jobid, 'dropboxtoken' );
|
60 |
?>
|
61 |
|
62 |
+
<h3 class="title"><?php _e( 'Login', 'backwpup' ); ?></h3>
|
63 |
+
<p></p>
|
64 |
+
<table class="form-table">
|
65 |
+
<tr>
|
66 |
+
<th scope="row"><?php _e( 'Authentication', 'backwpup' ); ?></th>
|
67 |
+
<td><?php if ( empty( $dropboxtoken['access_token'] ) ) { ?>
|
68 |
+
<span style="color:red;"><?php _e( 'Not authenticated!', 'backwpup' ); ?></span><br/> <br/>
|
69 |
+
<a class="button secondary"
|
70 |
+
href="http://db.tt/8irM1vQ0"><?php _e( 'Create Account', 'backwpup' ); ?></a>
|
71 |
+
<?php } else { ?>
|
72 |
+
<span style="color:green;"><?php _e( 'Authenticated!', 'backwpup' ); ?></span><br/> <br/>
|
73 |
+
<a class="button secondary"
|
74 |
+
href="<?php echo network_admin_url( 'admin.php' ) . '?page=backwpupeditjob&deleteauth=1&jobid=' . $jobid . '&tab=dest-dropbox&_wpnonce=' . wp_create_nonce( 'edit-job' ); ?>"
|
75 |
+
title="<?php _e( 'Delete Dropbox Authentication', 'backwpup' ); ?>"><?php _e( 'Delete Dropbox Authentication', 'backwpup' ); ?></a>
|
76 |
+
<?php } ?>
|
77 |
+
</td>
|
78 |
+
</tr>
|
79 |
+
|
80 |
+
<?php if ( empty( $dropboxtoken['access_token'] ) ) { ?>
|
81 |
+
<tr>
|
82 |
+
<th scope="row"><label
|
83 |
+
for="id_sandbox_code"><?php _e( 'App Access to Dropbox', 'backwpup' ); ?></label></th>
|
84 |
+
<td>
|
85 |
+
<input id="id_sandbox_code" name="sandbox_code" type="text" value=""
|
86 |
+
class="regular-text code help-tip"
|
87 |
+
title="<?php esc_attr_e( 'A dedicated folder named BackWPup will be created inside of the Apps folder in your Dropbox. BackWPup will get read and write access to that folder only. You can specify a subfolder as your backup destination for this job in the destination field below.', 'backwpup' ); ?>"/>
|
88 |
+
<a class="button secondary" href="<?php echo $sandbox_auth_url; ?>"
|
89 |
+
target="_blank"><?php _e( 'Get Dropbox App auth code', 'backwpup' ); ?></a>
|
90 |
+
<p><em><?php _e( 'Allows restricted access to Apps/BackWPup folder only.', 'backwpup' ); ?></em>
|
91 |
+
</p>
|
92 |
+
</td>
|
93 |
+
</tr>
|
94 |
+
<tr>
|
95 |
+
<th></th>
|
96 |
+
<td><?php _e( '— OR —', 'backwpup' ); ?></td>
|
97 |
+
</tr>
|
98 |
+
<tr>
|
99 |
+
<th scope="row"><label
|
100 |
+
for="id_dropbbox_code"><?php _e( 'Full Access to Dropbox', 'backwpup' ); ?></label></th>
|
101 |
+
<td>
|
102 |
+
<input id="id_dropbbox_code" name="dropbbox_code" type="text" value=""
|
103 |
+
class="regular-text code help-tip"
|
104 |
+
title="<?php _e( 'BackWPup will have full read and write access to your entire Dropbox. You can specify your backup destination wherever you want, just be aware that ANY files or folders inside of your Dropbox can be overridden or deleted by BackWPup.', 'backwpup' ); ?>"/>
|
105 |
+
<a class="button secondary" href="<?php echo $dropbox_auth_url; ?>"
|
106 |
+
target="_blank"><?php _e( 'Get full Dropbox auth code ', 'backwpup' ); ?></a>
|
107 |
+
<p><em><?php _e( 'Allows full access to your entire Dropbox.', 'backwpup' ); ?></em></p>
|
108 |
+
</td>
|
109 |
+
</tr>
|
110 |
+
<?php } ?>
|
111 |
+
</table>
|
112 |
+
|
113 |
+
|
114 |
+
<h3 class="title"><?php _e( 'Backup settings', 'backwpup' ); ?></h3>
|
115 |
+
<p></p>
|
116 |
+
<table class="form-table">
|
117 |
+
<tr>
|
118 |
+
<th scope="row"><label for="iddropboxdir"><?php _e( 'Destination Folder', 'backwpup' ); ?></label></th>
|
119 |
+
<td>
|
120 |
+
<input id="iddropboxdir" name="dropboxdir" type="text"
|
121 |
+
value="<?php echo esc_attr( BackWPup_Option::get( $jobid, 'dropboxdir' ) ); ?>"
|
122 |
+
class="regular-text help-tip"
|
123 |
+
title="<?php esc_attr_e( 'Specify a subfolder where your backup archives will be stored. If you use the App option from above, this folder will be created inside of Apps/BackWPup. Otherwise it will be created at the root of your Dropbox. Already exisiting folders with the same name will not be overriden.', 'backwpup' ); ?>"/>
|
124 |
+
<p>
|
125 |
+
<em><?php _e( 'Folder inside your Dropbox where your backup archives will be stored.', 'backwpup' ); ?></em>
|
126 |
+
</p>
|
127 |
+
</td>
|
128 |
+
</tr>
|
129 |
+
<tr>
|
130 |
+
<th scope="row"><?php _e( 'File Deletion', 'backwpup' ); ?></th>
|
131 |
+
<td>
|
132 |
+
<?php
|
133 |
+
if ( BackWPup_Option::get( $jobid, 'backuptype' ) == 'archive' ) {
|
134 |
+
?>
|
135 |
+
<label for="iddropboxmaxbackups"><input id="iddropboxmaxbackups" name="dropboxmaxbackups"
|
136 |
+
title="<?php esc_attr_e( 'Older files will be deleted first. 0 = no files will be deleted.', 'backwpup' ); ?>"
|
137 |
+
type="text" size="3"
|
138 |
+
value="<?php echo esc_attr( BackWPup_Option::get( $jobid, 'dropboxmaxbackups' ) ); ?>"
|
139 |
+
class="small-text help-tip"/>
|
140 |
+
<em><?php _e( 'Number of files to keep in folder.', 'backwpup' ); ?></em></label>
|
141 |
<?php } else { ?>
|
142 |
+
<label for="iddropboxsyncnodelete"><input class="checkbox" value="1"
|
143 |
+
type="checkbox" <?php checked( BackWPup_Option::get( $jobid, 'dropboxsyncnodelete' ), true ); ?>
|
144 |
+
name="dropboxsyncnodelete"
|
145 |
+
id="iddropboxsyncnodelete"/> <?php _e( 'Do not delete files while syncing to destination!', 'backwpup' ); ?>
|
146 |
+
</label>
|
147 |
<?php } ?>
|
148 |
+
</td>
|
149 |
+
</tr>
|
150 |
+
</table>
|
151 |
|
152 |
+
<?php
|
153 |
}
|
154 |
|
155 |
/**
|
156 |
* @param $jobid
|
157 |
+
*
|
158 |
* @return string|void
|
159 |
*/
|
160 |
public function edit_form_post_save( $jobid ) {
|
161 |
|
162 |
// get auth
|
163 |
+
if ( ! empty( $_POST['sandbox_code'] ) ) {
|
164 |
try {
|
165 |
+
$dropbox = new BackWPup_Destination_Dropbox_API( 'sandbox' );
|
166 |
+
$dropboxtoken = $dropbox->oAuthToken( $_POST['sandbox_code'] );
|
167 |
BackWPup_Option::update( $jobid, 'dropboxtoken', $dropboxtoken );
|
168 |
BackWPup_Option::update( $jobid, 'dropboxroot', 'sandbox' );
|
169 |
} catch ( Exception $e ) {
|
170 |
+
BackWPup_Admin::message( 'DROPBOX: ' . $e->getMessage(), true );
|
171 |
}
|
172 |
}
|
173 |
|
174 |
+
if ( ! empty( $_POST['dropbbox_code'] ) ) {
|
175 |
try {
|
176 |
+
$dropbox = new BackWPup_Destination_Dropbox_API( 'dropbox' );
|
177 |
+
$dropboxtoken = $dropbox->oAuthToken( $_POST['dropbbox_code'] );
|
178 |
BackWPup_Option::update( $jobid, 'dropboxtoken', $dropboxtoken );
|
179 |
BackWPup_Option::update( $jobid, 'dropboxroot', 'dropbox' );
|
180 |
} catch ( Exception $e ) {
|
181 |
+
BackWPup_Admin::message( 'DROPBOX: ' . $e->getMessage(), true );
|
182 |
}
|
183 |
}
|
184 |
|
185 |
+
BackWPup_Option::update( $jobid, 'dropboxsyncnodelete', ( isset( $_POST['dropboxsyncnodelete'] ) && $_POST['dropboxsyncnodelete'] == 1 ) ? true : false );
|
186 |
+
BackWPup_Option::update( $jobid, 'dropboxmaxbackups', isset( $_POST['dropboxmaxbackups'] ) ? (int) $_POST['dropboxmaxbackups'] : 0 );
|
187 |
|
188 |
+
$_POST['dropboxdir'] = trailingslashit( str_replace( '//', '/', str_replace( '\\', '/', trim( stripslashes( $_POST['dropboxdir'] ) ) ) ) );
|
189 |
+
if ( substr( $_POST['dropboxdir'], 0, 1 ) == '/' ) {
|
190 |
+
$_POST['dropboxdir'] = substr( $_POST['dropboxdir'], 1 );
|
191 |
+
}
|
192 |
+
if ( $_POST['dropboxdir'] == '/' ) {
|
193 |
+
$_POST['dropboxdir'] = '';
|
194 |
+
}
|
195 |
+
BackWPup_Option::update( $jobid, 'dropboxdir', $_POST['dropboxdir'] );
|
196 |
|
197 |
}
|
198 |
|
211 |
$dropbox->fileopsDelete( $backupfile );
|
212 |
//update file list
|
213 |
foreach ( $files as $key => $file ) {
|
214 |
+
if ( is_array( $file ) && $file['file'] == $backupfile ) {
|
215 |
unset( $files[ $key ] );
|
216 |
+
}
|
217 |
}
|
218 |
unset( $dropbox );
|
219 |
+
} catch ( Exception $e ) {
|
220 |
+
BackWPup_Admin::message( 'DROPBOX: ' . $e->getMessage(), true );
|
|
|
221 |
}
|
222 |
|
223 |
set_site_transient( 'backwpup_' . strtolower( $jobdest ), $files, 3600 * 24 * 7 );
|
233 |
$dropbox = new BackWPup_Destination_Dropbox_API( BackWPup_Option::get( $jobid, 'dropboxroot' ) );
|
234 |
$dropbox->setOAuthTokens( BackWPup_Option::get( $jobid, 'dropboxtoken' ) );
|
235 |
$media = $dropbox->media( $get_file );
|
236 |
+
if ( ! empty( $media['url'] ) ) {
|
237 |
+
header( "Location: " . $media['url'] );
|
238 |
+
}
|
239 |
die();
|
240 |
+
} catch ( Exception $e ) {
|
|
|
241 |
die( $e->getMessage() );
|
242 |
}
|
243 |
}
|
244 |
|
245 |
/**
|
246 |
* @param $jobdest
|
247 |
+
*
|
248 |
* @return mixed
|
249 |
*/
|
250 |
public function file_get_list( $jobdest ) {
|
253 |
|
254 |
/**
|
255 |
* @param $job_object
|
256 |
+
*
|
257 |
* @return bool
|
258 |
*/
|
259 |
public function job_run_archive( BackWPup_Job $job_object ) {
|
260 |
|
261 |
$job_object->substeps_todo = 2 + $job_object->backup_filesize;
|
262 |
+
if ( $job_object->steps_data[ $job_object->step_working ]['SAVE_STEP_TRY'] != $job_object->steps_data[ $job_object->step_working ]['STEP_TRY'] ) {
|
263 |
+
$job_object->log( sprintf( __( '%d. Try to send backup file to Dropbox …', 'backwpup' ), $job_object->steps_data[ $job_object->step_working ]['STEP_TRY'] ) );
|
264 |
+
}
|
265 |
|
266 |
try {
|
267 |
+
$dropbox = new BackWPup_Destination_Dropbox_API( $job_object->job['dropboxroot'] );
|
268 |
// cahnge oauth1 to oauth2 token
|
269 |
+
if ( ! empty( $job_object->job['dropboxsecret'] ) && empty( $job_object->job['dropboxtoken']['access_token'] ) ) {
|
270 |
+
$dropbox->setOAuthTokens( array(
|
271 |
+
'access_token' => $job_object->job['dropboxtoken'],
|
272 |
+
'oauth_token_secret' => BackWPup_Encryption::decrypt( $job_object->job['dropboxsecret'] )
|
273 |
+
) );
|
274 |
+
$job_object->job['dropboxtoken'] = $dropbox->token_from_oauth1();
|
275 |
+
BackWPup_Option::update( $job_object->job['jobid'], 'dropboxtoken', $job_object->job['dropboxtoken'] );
|
276 |
+
BackWPup_Option::delete( $job_object->job['jobid'], 'dropboxsecret' );
|
277 |
}
|
278 |
// set the tokens
|
279 |
+
$dropbox->setOAuthTokens( $job_object->job['dropboxtoken'] );
|
280 |
|
281 |
//get account info
|
282 |
+
if ( $job_object->steps_data[ $job_object->step_working ]['SAVE_STEP_TRY'] != $job_object->steps_data[ $job_object->step_working ]['STEP_TRY'] ) {
|
283 |
$info = $dropbox->accountInfo();
|
284 |
+
if ( ! empty( $info['uid'] ) ) {
|
285 |
if ( $job_object->is_debug() ) {
|
286 |
+
$user = $info['display_name'] . ' (' . $info['email'] . ')';
|
287 |
} else {
|
288 |
+
$user = $info['display_name'];
|
289 |
}
|
290 |
$job_object->log( sprintf( __( 'Authenticated with Dropbox of user: %s', 'backwpup' ), $user ) );
|
291 |
//Quota
|
292 |
if ( $job_object->is_debug() ) {
|
293 |
+
$dropboxfreespase = $info['quota_info']['quota'] - $info['quota_info']['shared'] - $info['quota_info']['normal'];
|
294 |
$job_object->log( sprintf( __( '%s available on your Dropbox', 'backwpup' ), size_format( $dropboxfreespase, 2 ) ) );
|
295 |
}
|
296 |
} else {
|
297 |
$job_object->log( __( 'Not Authenticated with Dropbox!', 'backwpup' ), E_USER_ERROR );
|
298 |
+
|
299 |
+
return false;
|
300 |
}
|
301 |
$job_object->log( __( 'Uploading to Dropbox …', 'backwpup' ) );
|
302 |
}
|
305 |
self::$backwpup_job_object = &$job_object;
|
306 |
|
307 |
if ( $job_object->substeps_done < $job_object->backup_filesize ) { //only if upload not complete
|
308 |
+
$response = $dropbox->upload( $job_object->backup_folder . $job_object->backup_file, $job_object->job['dropboxdir'] . $job_object->backup_file );
|
309 |
+
if ( $response['bytes'] == $job_object->backup_filesize ) {
|
310 |
+
if ( ! empty( $job_object->job['jobid'] ) ) {
|
311 |
+
BackWPup_Option::update( $job_object->job['jobid'], 'lastbackupdownloadurl', network_admin_url( 'admin.php' ) . '?page=backwpupbackups&action=downloaddropbox&file=' . ltrim( $response['path'], '/' ) . '&jobid=' . $job_object->job['jobid'] );
|
312 |
+
}
|
313 |
$job_object->substeps_done = 1 + $job_object->backup_filesize;
|
314 |
+
$job_object->log( sprintf( __( 'Backup transferred to %s', 'backwpup' ), 'https://content.dropboxapi.com/1/files/' . $job_object->job['dropboxroot'] . $response['path'] ), E_USER_NOTICE );
|
315 |
+
} else {
|
316 |
+
if ( $response['bytes'] != $job_object->backup_filesize ) {
|
|
|
317 |
$job_object->log( __( 'Uploaded file size and local file size don\'t match.', 'backwpup' ), E_USER_ERROR );
|
318 |
+
} else {
|
319 |
$job_object->log(
|
320 |
+
sprintf(
|
321 |
+
__( 'Error transfering backup to %s.', 'backwpup' ) . ' ' . $response['error'],
|
322 |
+
__( 'Dropbox', 'backwpup' )
|
323 |
+
), E_USER_ERROR );
|
324 |
+
}
|
325 |
|
326 |
+
return false;
|
327 |
}
|
328 |
}
|
329 |
|
331 |
$backupfilelist = array();
|
332 |
$filecounter = 0;
|
333 |
$files = array();
|
334 |
+
$metadata = $dropbox->metadata( $job_object->job['dropboxdir'] );
|
335 |
if ( is_array( $metadata ) ) {
|
336 |
+
foreach ( $metadata['contents'] as $data ) {
|
337 |
+
if ( $data['is_dir'] != true ) {
|
338 |
+
$file = basename( $data['path'] );
|
339 |
if ( $job_object->is_backup_archive( $file ) ) {
|
340 |
+
$backupfilelist[ strtotime( $data['modified'] ) ] = $file;
|
341 |
}
|
342 |
+
$files[ $filecounter ]['folder'] = "https://content.dropboxapi.com/1/files/" . $job_object->job['dropboxroot'] . dirname( $data['path'] ) . "/";
|
343 |
+
$files[ $filecounter ]['file'] = $data['path'];
|
344 |
+
$files[ $filecounter ]['filename'] = basename( $data['path'] );
|
345 |
+
$files[ $filecounter ]['downloadurl'] = network_admin_url( 'admin.php' ) . '?page=backwpupbackups&action=downloaddropbox&file=' . $data['path'] . '&jobid=' . $job_object->job['jobid'];
|
346 |
+
$files[ $filecounter ]['filesize'] = $data['bytes'];
|
347 |
+
$files[ $filecounter ]['time'] = strtotime( $data['modified'] ) + ( get_option( 'gmt_offset' ) * 3600 );
|
348 |
$filecounter ++;
|
349 |
}
|
350 |
}
|
351 |
}
|
352 |
+
if ( $job_object->job['dropboxmaxbackups'] > 0 && is_object( $dropbox ) ) { //Delete old backups
|
353 |
+
if ( count( $backupfilelist ) > $job_object->job['dropboxmaxbackups'] ) {
|
354 |
ksort( $backupfilelist );
|
355 |
$numdeltefiles = 0;
|
356 |
while ( $file = array_shift( $backupfilelist ) ) {
|
357 |
+
if ( count( $backupfilelist ) < $job_object->job['dropboxmaxbackups'] ) {
|
358 |
break;
|
359 |
+
}
|
360 |
+
$response = $dropbox->fileopsDelete( $job_object->job['dropboxdir'] . $file ); //delete files on Cloud
|
361 |
+
if ( $response['is_deleted'] == 'true' ) {
|
362 |
foreach ( $files as $key => $filedata ) {
|
363 |
+
if ( $filedata['file'] == '/' . $job_object->job['dropboxdir'] . $file ) {
|
364 |
unset( $files[ $key ] );
|
365 |
+
}
|
366 |
}
|
367 |
$numdeltefiles ++;
|
368 |
+
} else {
|
|
|
369 |
$job_object->log( sprintf( __( 'Error while deleting file from Dropbox: %s', 'backwpup' ), $file ), E_USER_ERROR );
|
370 |
+
}
|
371 |
}
|
372 |
+
if ( $numdeltefiles > 0 ) {
|
373 |
$job_object->log( sprintf( _n( 'One file deleted from Dropbox', '%d files deleted on Dropbox', $numdeltefiles, 'backwpup' ), $numdeltefiles ), E_USER_NOTICE );
|
374 |
+
}
|
375 |
}
|
376 |
}
|
377 |
+
set_site_transient( 'backwpup_' . $job_object->job['jobid'] . '_dropbox', $files, 60 * 60 * 24 * 7 );
|
378 |
+
} catch ( Exception $e ) {
|
|
|
379 |
$job_object->log( E_USER_ERROR, sprintf( __( 'Dropbox API: %s', 'backwpup' ), $e->getMessage() ), $e->getFile(), $e->getLine() );
|
380 |
|
381 |
+
return false;
|
382 |
}
|
383 |
$job_object->substeps_done ++;
|
384 |
|
385 |
+
return true;
|
386 |
}
|
387 |
|
388 |
/**
|
389 |
* @param $job_settings
|
390 |
+
*
|
391 |
* @return bool
|
392 |
*/
|
393 |
public function can_run( array $job_settings ) {
|
394 |
|
395 |
+
if ( empty( $job_settings['dropboxtoken'] ) ) {
|
396 |
+
return false;
|
397 |
+
}
|
398 |
|
399 |
+
return true;
|
400 |
}
|
401 |
|
402 |
}
|
410 |
/**
|
411 |
*
|
412 |
*/
|
413 |
+
const API_URL = 'https://api.dropboxapi.com/';
|
414 |
|
415 |
/**
|
416 |
*
|
417 |
*/
|
418 |
+
const API_CONTENT_URL = 'https://content.dropboxapi.com/';
|
419 |
|
420 |
/**
|
421 |
*
|
422 |
*/
|
423 |
+
const API_WWW_URL = 'https://www.dropbox.com/';
|
424 |
|
425 |
/**
|
426 |
*
|
451 |
private $oauth_token = '';
|
452 |
|
453 |
|
|
|
454 |
/**
|
455 |
* @param string $boxtype
|
456 |
+
*
|
457 |
* @throws BackWPup_Destination_Dropbox_API_Exception
|
458 |
*/
|
459 |
public function __construct( $boxtype = 'dropbox' ) {
|
460 |
|
461 |
if ( $boxtype == 'dropbox' ) {
|
462 |
+
$this->oauth_app_key = get_site_option( 'backwpup_cfg_dropboxappkey', base64_decode( "dHZkcjk1MnRhZnM1NmZ2" ) );
|
463 |
$this->oauth_app_secret = BackWPup_Encryption::decrypt( get_site_option( 'backwpup_cfg_dropboxappsecret', base64_decode( "OWV2bDR5MHJvZ2RlYmx1" ) ) );
|
464 |
$this->root = 'dropbox';
|
465 |
+
} else {
|
466 |
+
$this->oauth_app_key = get_site_option( 'backwpup_cfg_dropboxsandboxappkey', base64_decode( "cHVrZmp1a3JoZHR5OTFk" ) );
|
|
|
467 |
$this->oauth_app_secret = BackWPup_Encryption::decrypt( get_site_option( 'backwpup_cfg_dropboxsandboxappsecret', base64_decode( "eGNoYzhxdTk5eHE0eWdq" ) ) );
|
468 |
$this->root = 'sandbox';
|
469 |
}
|
470 |
|
471 |
+
if ( empty( $this->oauth_app_key ) || empty( $this->oauth_app_secret ) ) {
|
472 |
throw new BackWPup_Destination_Dropbox_API_Exception( "No App key or App Secret specified." );
|
473 |
+
}
|
474 |
}
|
475 |
|
476 |
/**
|
477 |
* @param $token
|
478 |
+
*
|
479 |
* @throws BackWPup_Destination_Dropbox_API_Exception
|
480 |
*/
|
481 |
public function setOAuthTokens( $token ) {
|
482 |
|
483 |
+
if ( empty( $token['access_token'] ) ) {
|
484 |
throw new BackWPup_Destination_Dropbox_API_Exception( "No oAuth token specified." );
|
485 |
+
}
|
486 |
|
487 |
$this->oauth_token = $token;
|
488 |
}
|
489 |
|
490 |
+
public function token_from_oauth1() {
|
491 |
|
492 |
$url = self::API_URL . self::API_VERSION_URL . 'oauth2/token_from_oauth1';
|
493 |
|
514 |
/**
|
515 |
* @param $file
|
516 |
* @param string $path
|
517 |
+
* @param bool $overwrite
|
518 |
+
*
|
519 |
* @return array|mixed|string
|
520 |
* @throws BackWPup_Destination_Dropbox_API_Exception
|
521 |
*/
|
522 |
+
public function upload( $file, $path = '', $overwrite = true ) {
|
523 |
|
524 |
$file = str_replace( "\\", "/", $file );
|
525 |
|
528 |
}
|
529 |
|
530 |
if ( filesize( $file ) < 5242880 ) { //chunk transfer on bigger uploads
|
531 |
+
$url = self::API_CONTENT_URL . self::API_VERSION_URL . 'files_put/' . $this->root . '/' . $this->encode_path( $path );
|
532 |
+
$output = $this->request( $url, array( 'overwrite' => ( $overwrite ) ? 'true' : 'false' ), 'PUT', file_get_contents( $file ) );
|
533 |
+
} else {
|
|
|
534 |
$output = $this->chunked_upload( $file, $path, $overwrite );
|
535 |
}
|
536 |
|
540 |
/**
|
541 |
* @param $file
|
542 |
* @param string $path
|
543 |
+
* @param bool $overwrite
|
544 |
+
*
|
545 |
* @return array|mixed|string
|
546 |
* @throws BackWPup_Destination_Dropbox_API_Exception
|
547 |
*/
|
548 |
+
public function chunked_upload( $file, $path = '', $overwrite = true ) {
|
549 |
|
550 |
$backwpup_job_object = BackWPup_Destination_Dropbox::$backwpup_job_object;
|
551 |
|
562 |
throw new BackWPup_Destination_Dropbox_API_Exception( "Can not open source file for transfer." );
|
563 |
}
|
564 |
|
565 |
+
if ( ! isset( $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['uploadid'] ) ) {
|
566 |
+
$backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['uploadid'] = null;
|
567 |
}
|
568 |
+
if ( ! isset( $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['offset'] ) ) {
|
569 |
+
$backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['offset'] = 0;
|
570 |
}
|
571 |
|
572 |
//seek to current position
|
573 |
+
if ( $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['offset'] > 0 ) {
|
574 |
+
fseek( $file_handel, $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['offset'] );
|
575 |
}
|
576 |
|
577 |
while ( $data = fread( $file_handel, $chunk_size ) ) {
|
578 |
+
$chunk_upload_start = microtime( true );
|
579 |
+
$url = self::API_CONTENT_URL . self::API_VERSION_URL . 'chunked_upload';
|
580 |
+
$output = $this->request( $url, array(
|
581 |
+
'upload_id' => $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['uploadid'],
|
582 |
+
'offset' => $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['offset']
|
583 |
+
), 'PUT', $data );
|
584 |
+
$chunk_upload_time = microtime( true ) - $chunk_upload_start;
|
585 |
//args for next chunk
|
586 |
+
$backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['offset'] = $output['offset'];
|
587 |
+
$backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['uploadid'] = $output['upload_id'];
|
588 |
+
if ( $backwpup_job_object->job['backuptype'] === 'archive' ) {
|
589 |
+
$backwpup_job_object->substeps_done = $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['offset'];
|
590 |
if ( strlen( $data ) == $chunk_size ) {
|
591 |
$time_remaining = $backwpup_job_object->do_restart_time();
|
592 |
//calc next chunk
|
593 |
if ( $time_remaining < $chunk_upload_time ) {
|
594 |
+
$chunk_size = floor( $chunk_size / $chunk_upload_time * ( $time_remaining - 3 ) );
|
595 |
if ( $chunk_size < 0 ) {
|
596 |
$chunk_size = 1024;
|
597 |
}
|
603 |
}
|
604 |
$backwpup_job_object->update_working_data();
|
605 |
//correct position
|
606 |
+
fseek( $file_handel, $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['offset'] );
|
607 |
}
|
608 |
|
609 |
fclose( $file_handel );
|
610 |
|
611 |
$url = self::API_CONTENT_URL . self::API_VERSION_URL . 'commit_chunked_upload/' . $this->root . '/' . $this->encode_path( $path );
|
612 |
|
613 |
+
$request = $this->request( $url, array(
|
614 |
+
'overwrite' => ( $overwrite ) ? 'true' : 'false',
|
615 |
+
'upload_id' => $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['uploadid']
|
616 |
+
), 'POST' );
|
617 |
+
|
618 |
+
unset( $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['uploadid'] );
|
619 |
+
unset( $backwpup_job_object->steps_data[ $backwpup_job_object->step_working ]['offset'] );
|
620 |
+
|
621 |
+
return $request;
|
622 |
}
|
623 |
|
624 |
/**
|
625 |
* @param $path
|
626 |
* @param bool $echo
|
627 |
+
*
|
628 |
* @return string
|
629 |
*/
|
630 |
+
public function download( $path, $echo = false ) {
|
631 |
|
632 |
+
$url = self::API_CONTENT_URL . self::API_VERSION_URL . 'files/' . $this->root . '/' . $path;
|
633 |
+
if ( ! $echo ) {
|
634 |
return $this->request( $url );
|
635 |
+
} else {
|
636 |
+
$this->request( $url, null, 'GET', '', true );
|
637 |
+
|
638 |
return '';
|
639 |
}
|
640 |
}
|
641 |
|
642 |
/**
|
643 |
* @param string $path
|
644 |
+
* @param bool $listContents
|
645 |
+
* @param int $fileLimit
|
646 |
* @param string $hash
|
647 |
+
*
|
648 |
* @return array|mixed|string
|
649 |
*/
|
650 |
+
public function metadata( $path = '', $listContents = true, $fileLimit = 10000, $hash = '' ) {
|
651 |
|
652 |
$url = self::API_URL . self::API_VERSION_URL . 'metadata/' . $this->root . '/' . $this->encode_path( $path );
|
653 |
|
654 |
return $this->request( $url, array(
|
655 |
+
'list' => ( $listContents ) ? 'true' : 'false',
|
656 |
+
'hash' => ( $hash ) ? $hash : '',
|
657 |
+
'file_limit' => $fileLimit
|
658 |
+
) );
|
659 |
}
|
660 |
|
661 |
/**
|
662 |
* @param string $path
|
663 |
+
*
|
664 |
* @return array|mixed|string
|
665 |
*/
|
666 |
public function media( $path = '' ) {
|
672 |
|
673 |
/**
|
674 |
* @param $path
|
675 |
+
*
|
676 |
* @return array|mixed|string
|
677 |
*/
|
678 |
public function fileopsDelete( $path ) {
|
680 |
$url = self::API_URL . self::API_VERSION_URL . 'fileops/delete';
|
681 |
|
682 |
return $this->request( $url, array(
|
683 |
+
'path' => '/' . $path,
|
684 |
+
'root' => $this->root
|
685 |
+
) );
|
686 |
}
|
687 |
|
688 |
+
public function oAuthAuthorize() {
|
689 |
|
690 |
return self::API_WWW_URL . self::API_VERSION_URL . 'oauth2/authorize?response_type=code&client_id=' . $this->oauth_app_key;
|
691 |
}
|
696 |
$url = self::API_URL . self::API_VERSION_URL . 'oauth2/token';
|
697 |
|
698 |
return $this->request( $url, array(
|
699 |
+
'code' => trim( $code ),
|
700 |
+
'grant_type' => 'authorization_code',
|
701 |
+
'client_id' => $this->oauth_app_key,
|
702 |
+
'client_secret' => $this->oauth_app_secret
|
703 |
+
), 'POST' );
|
704 |
|
705 |
}
|
706 |
|
707 |
|
708 |
/**
|
709 |
* @param $url
|
710 |
+
* @param array $args
|
711 |
* @param string $method
|
712 |
* @param string $data
|
713 |
+
* @param bool $echo
|
714 |
*
|
715 |
* @throws BackWPup_Destination_Dropbox_API_Exception
|
716 |
* @internal param null $file
|
717 |
* @return array|mixed|string
|
718 |
*/
|
719 |
+
private function request( $url, $args = array(), $method = 'GET', $data = '', $echo = false ) {
|
720 |
|
721 |
/* Header*/
|
722 |
// oAuth 2
|
723 |
+
if ( ! empty( $this->oauth_token['access_token'] ) && ! empty( $this->oauth_token['token_type'] ) && strtolower( $this->oauth_token['token_type'] ) == 'bearer' ) {
|
724 |
+
$headers[] = 'Authorization: Bearer ' . $this->oauth_token['access_token'];
|
725 |
+
} // oAuth 1
|
726 |
+
elseif ( ! empty( $this->oauth_token['access_token'] ) && ! empty( $this->oauth_token['oauth_token_secret'] ) ) {
|
727 |
+
$headers[] = 'Authorization: OAuth oauth_version="1.0", oauth_signature_method="PLAINTEXT", oauth_consumer_key="' . $this->oauth_app_key . '", oauth_token="' . $this->oauth_token['access_token'] . '", oauth_signature="' . $this->oauth_app_secret . '&' . $this->oauth_token['oauth_token_secret'] . '"';
|
728 |
+
}
|
729 |
|
730 |
+
$headers[] = 'Expect:';
|
731 |
|
732 |
/* Build cURL Request */
|
733 |
$ch = curl_init();
|
734 |
if ( $method == 'POST' ) {
|
735 |
+
curl_setopt( $ch, CURLOPT_POST, true );
|
736 |
curl_setopt( $ch, CURLOPT_POSTFIELDS, $args );
|
737 |
curl_setopt( $ch, CURLOPT_URL, $url );
|
738 |
+
} elseif ( $method == 'PUT' ) {
|
|
|
739 |
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'PUT' );
|
740 |
curl_setopt( $ch, CURLOPT_POSTFIELDS, $data );
|
741 |
+
$headers[] = 'Content-Type: application/octet-stream';
|
742 |
+
$args = ( is_array( $args ) ) ? '?' . http_build_query( $args, '', '&' ) : $args;
|
743 |
curl_setopt( $ch, CURLOPT_URL, $url . $args );
|
744 |
+
} else {
|
745 |
+
curl_setopt( $ch, CURLOPT_BINARYTRANSFER, true );
|
|
|
746 |
$args = ( is_array( $args ) ) ? '?' . http_build_query( $args, '', '&' ) : $args;
|
747 |
curl_setopt( $ch, CURLOPT_URL, $url . $args );
|
748 |
}
|
749 |
curl_setopt( $ch, CURLOPT_USERAGENT, BackWPup::get_plugin_data( 'User-Agent' ) );
|
750 |
+
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
|
751 |
if ( BackWPup::get_plugin_data( 'cacert' ) ) {
|
752 |
curl_setopt( $ch, CURLOPT_SSLVERSION, 1 );
|
753 |
+
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true );
|
754 |
$curl_version = curl_version();
|
755 |
+
if ( strstr( $curl_version['ssl_version'], 'NSS/' ) === false ) {
|
756 |
curl_setopt( $ch, CURLOPT_SSL_CIPHER_LIST,
|
757 |
+
'ECDHE-RSA-AES256-GCM-SHA384:' .
|
758 |
+
'ECDHE-RSA-AES128-GCM-SHA256:' .
|
759 |
+
'ECDHE-RSA-AES256-SHA384:' .
|
760 |
+
'ECDHE-RSA-AES128-SHA256:' .
|
761 |
+
'ECDHE-RSA-AES256-SHA:' .
|
762 |
+
'ECDHE-RSA-AES128-SHA:' .
|
763 |
+
'ECDHE-RSA-RC4-SHA:' .
|
764 |
+
'DHE-RSA-AES256-GCM-SHA384:' .
|
765 |
+
'DHE-RSA-AES128-GCM-SHA256:' .
|
766 |
+
'DHE-RSA-AES256-SHA256:' .
|
767 |
+
'DHE-RSA-AES128-SHA256:' .
|
768 |
+
'DHE-RSA-AES256-SHA:' .
|
769 |
+
'DHE-RSA-AES128-SHA:' .
|
770 |
+
'AES256-GCM-SHA384:' .
|
771 |
+
'AES128-GCM-SHA256:' .
|
772 |
+
'AES256-SHA256:' .
|
773 |
+
'AES128-SHA256:' .
|
774 |
+
'AES256-SHA:' .
|
775 |
+
'AES128-SHA'
|
776 |
);
|
777 |
}
|
778 |
+
if ( defined( 'CURLOPT_PROTOCOLS' ) ) {
|
779 |
curl_setopt( $ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTPS );
|
780 |
+
}
|
781 |
+
if ( defined( 'CURLOPT_REDIR_PROTOCOLS' ) ) {
|
782 |
curl_setopt( $ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTPS );
|
783 |
+
}
|
784 |
curl_setopt( $ch, CURLOPT_CAINFO, BackWPup::get_plugin_data( 'cacert' ) );
|
785 |
curl_setopt( $ch, CURLOPT_CAPATH, dirname( BackWPup::get_plugin_data( 'cacert' ) ) );
|
786 |
} else {
|
787 |
+
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
|
788 |
}
|
789 |
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
|
790 |
$output = '';
|
791 |
if ( $echo ) {
|
792 |
echo curl_exec( $ch );
|
793 |
+
} else {
|
794 |
+
curl_setopt( $ch, CURLOPT_HEADER, true );
|
|
|
795 |
if ( 0 == curl_errno( $ch ) ) {
|
796 |
$responce = explode( "\r\n\r\n", curl_exec( $ch ), 2 );
|
797 |
+
if ( ! empty( $responce[1] ) ) {
|
798 |
+
$output = json_decode( $responce[1], true );
|
799 |
+
}
|
800 |
}
|
801 |
}
|
802 |
$status = curl_getinfo( $ch );
|
803 |
+
if ( $status['http_code'] == 503 ) {
|
804 |
$wait = 0;
|
805 |
+
if ( preg_match( "/retry-after:(.*?)\r/i", $responce[0], $matches ) ) {
|
806 |
+
$wait = trim( $matches[1] );
|
807 |
+
}
|
808 |
//only wait if we get a retry-after header.
|
809 |
if ( ! empty( $wait ) ) {
|
810 |
trigger_error( sprintf( '(503) Your app is making too many requests and is being rate limited. Error 503 can be triggered on a per-app or per-user basis. Wait for %d seconds.', $wait ), E_USER_WARNING );
|
812 |
} else {
|
813 |
throw new BackWPup_Destination_Dropbox_API_Exception( '(503) This indicates a transient server error.' );
|
814 |
}
|
815 |
+
|
816 |
//redo request
|
817 |
return $this->request( $url, $args, $method, $data, $echo );
|
818 |
+
} elseif ( $status['http_code'] === 400 && $method === 'PUT' && strstr( $url, '/chunked_upload' ) ) { //correct offset on chunk uploads
|
819 |
+
trigger_error( '(' . $status['http_code'] . ') False offset will corrected', E_USER_NOTICE );
|
|
|
|
|
|
|
|
|
|
|
820 |
|
821 |
+
return $output;
|
822 |
+
} elseif ( $status['http_code'] === 404 && ! empty( $output['error'] ) ) {
|
823 |
+
trigger_error( '(' . $status['http_code'] . ') ' . $output['error'], E_USER_WARNING );
|
824 |
+
|
825 |
+
return false;
|
826 |
+
} elseif ( isset( $output['error'] ) || $status['http_code'] >= 300 || $status['http_code'] < 200 || curl_errno( $ch ) > 0 ) {
|
827 |
+
if ( isset( $output['error'] ) && is_string( $output['error'] ) ) {
|
828 |
+
$message = '(' . $status['http_code'] . ') ' . $output['error'] . ' ' . $url . $args;
|
829 |
+
} elseif ( isset( $output['error']['hash'] ) && $output['error']['hash'] != '' ) {
|
830 |
+
$message = (string) '(' . $status['http_code'] . ') ' . $output['error']['hash'] . ' ' . $url . $args;
|
831 |
+
} elseif ( 0 != curl_errno( $ch ) ) {
|
832 |
+
$message = '(' . curl_errno( $ch ) . ') ' . curl_error( $ch );
|
833 |
+
} elseif ( $status['http_code'] == 304 ) {
|
834 |
+
$message = '(304) Folder contents have not changed (relies on hash parameter).';
|
835 |
+
} elseif ( $status['http_code'] == 400 ) {
|
836 |
+
$message = '(400) Bad input parameter: ' . strip_tags( $responce[1] );
|
837 |
+
} elseif ( $status['http_code'] == 401 ) {
|
838 |
+
$message = '(401) Bad or expired token. This can happen if the user or Dropbox revoked or expired an access token. To fix, you should re-authenticate the user.';
|
839 |
+
} elseif ( $status['http_code'] == 403 ) {
|
840 |
+
$message = '(403) Bad OAuth request (wrong consumer key, bad nonce, expired timestamp...). Unfortunately, re-authenticating the user won\'t help here.';
|
841 |
+
} elseif ( $status['http_code'] == 404 ) {
|
842 |
+
$message = '(404) File or folder not found at the specified path.';
|
843 |
+
} elseif ( $status['http_code'] == 405 ) {
|
844 |
+
$message = '(405) Request method not expected (generally should be GET or POST).';
|
845 |
+
} elseif ( $status['http_code'] == 406 ) {
|
846 |
+
$message = '(406) There are too many file entries to return.';
|
847 |
+
} elseif ( $status['http_code'] == 411 ) {
|
848 |
+
$message = '(411) Missing Content-Length header (this endpoint doesn\'t support HTTP chunked transfer encoding).';
|
849 |
+
} elseif ( $status['http_code'] == 415 ) {
|
850 |
+
$message = '(415) The image is invalid and cannot be converted to a thumbnail.';
|
851 |
+
} elseif ( $status['http_code'] == 429 ) {
|
852 |
+
$message = '(429) Your app is making too many requests and is being rate limited. 429s can trigger on a per-app or per-user basis.';
|
853 |
+
} elseif ( $status['http_code'] == 507 ) {
|
854 |
+
$message = '(507) User is over Dropbox storage quota.';
|
855 |
+
} else {
|
856 |
+
$message = '(' . $status['http_code'] . ') Invalid response.';
|
857 |
+
}
|
858 |
throw new BackWPup_Destination_Dropbox_API_Exception( $message );
|
859 |
+
} else {
|
|
|
860 |
curl_close( $ch );
|
861 |
+
if ( ! is_array( $output ) ) {
|
862 |
+
return $responce[1];
|
863 |
+
} else {
|
864 |
return $output;
|
865 |
+
}
|
866 |
}
|
867 |
}
|
868 |
|
inc/class-destination-folder.php
CHANGED
@@ -101,7 +101,6 @@ class BackWPup_Destination_Folder extends BackWPup_Destinations {
|
|
101 |
$get_file = realpath( trailingslashit( $backup_dir ) . basename( $get_file ) );
|
102 |
|
103 |
if ( $get_file && is_readable( $get_file ) ) {
|
104 |
-
while( @ob_end_clean() );
|
105 |
header( "Pragma: public" );
|
106 |
header( "Expires: 0" );
|
107 |
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
|
101 |
$get_file = realpath( trailingslashit( $backup_dir ) . basename( $get_file ) );
|
102 |
|
103 |
if ( $get_file && is_readable( $get_file ) ) {
|
|
|
104 |
header( "Pragma: public" );
|
105 |
header( "Expires: 0" );
|
106 |
header( "Cache-Control: must-revalidate, post-check=0, pre-check=0" );
|
inc/class-job.php
CHANGED
@@ -452,7 +452,7 @@ final class BackWPup_Job {
|
|
452 |
|
453 |
$authentication = get_site_option( 'backwpup_cfg_authentication', array( 'method' => '', 'basic_user' => '', 'basic_password' => '', 'user_id' => 0, 'query_arg' => '' ) );
|
454 |
$url = site_url( 'wp-cron.php' );
|
455 |
-
$header = array();
|
456 |
$authurl = '';
|
457 |
$query_args = array( '_nonce' => substr( wp_hash( wp_nonce_tick() . 'backwpup_job_run-' . $starttype, 'nonce' ), - 12, 10 ), 'doing_wp_cron' => sprintf( '%.22F', microtime( true ) ) );
|
458 |
|
@@ -548,6 +548,9 @@ final class BackWPup_Job {
|
|
548 |
|
549 |
if ( ! in_array( $starttype, array( 'runnowlink', 'runext', 'restartalt' ) ) ) {
|
550 |
delete_transient( 'doing_cron' );
|
|
|
|
|
|
|
551 |
return wp_remote_post( $cron_request[ 'url' ], $cron_request[ 'args' ] );
|
552 |
}
|
553 |
|
@@ -858,10 +861,6 @@ final class BackWPup_Job {
|
|
858 |
}
|
859 |
}
|
860 |
}
|
861 |
-
//clear output buffer
|
862 |
-
ob_start();
|
863 |
-
while( @ob_end_clean() );
|
864 |
-
@flush();
|
865 |
$job_types = BackWPup::get_job_types();
|
866 |
//go step by step
|
867 |
foreach ( $this->steps_todo as $this->step_working ) {
|
@@ -2387,7 +2386,7 @@ final class BackWPup_Job {
|
|
2387 |
public static function clean_temp_folder() {
|
2388 |
|
2389 |
$temp_dir = BackWPup::get_plugin_data( 'TEMP' );
|
2390 |
-
$do_not_delete_files = array( '.htaccess', 'index.php', '.', '..', '.donotbackup' );
|
2391 |
|
2392 |
if ( is_writable( $temp_dir ) && $dir = opendir( $temp_dir ) ) {
|
2393 |
while ( FALSE !== ( $file = readdir( $dir ) ) ) {
|
452 |
|
453 |
$authentication = get_site_option( 'backwpup_cfg_authentication', array( 'method' => '', 'basic_user' => '', 'basic_password' => '', 'user_id' => 0, 'query_arg' => '' ) );
|
454 |
$url = site_url( 'wp-cron.php' );
|
455 |
+
$header = array( 'x-backwpup-version' => BackWPup::get_plugin_data( 'version' ) );
|
456 |
$authurl = '';
|
457 |
$query_args = array( '_nonce' => substr( wp_hash( wp_nonce_tick() . 'backwpup_job_run-' . $starttype, 'nonce' ), - 12, 10 ), 'doing_wp_cron' => sprintf( '%.22F', microtime( true ) ) );
|
458 |
|
548 |
|
549 |
if ( ! in_array( $starttype, array( 'runnowlink', 'runext', 'restartalt' ) ) ) {
|
550 |
delete_transient( 'doing_cron' );
|
551 |
+
if ( $starttype === 'test' ) {
|
552 |
+
return wp_remote_head( $cron_request[ 'url' ], $cron_request[ 'args' ] );
|
553 |
+
}
|
554 |
return wp_remote_post( $cron_request[ 'url' ], $cron_request[ 'args' ] );
|
555 |
}
|
556 |
|
861 |
}
|
862 |
}
|
863 |
}
|
|
|
|
|
|
|
|
|
864 |
$job_types = BackWPup::get_job_types();
|
865 |
//go step by step
|
866 |
foreach ( $this->steps_todo as $this->step_working ) {
|
2386 |
public static function clean_temp_folder() {
|
2387 |
|
2388 |
$temp_dir = BackWPup::get_plugin_data( 'TEMP' );
|
2389 |
+
$do_not_delete_files = array( '.htaccess', 'nginx.conf', 'index.php', '.', '..', '.donotbackup' );
|
2390 |
|
2391 |
if ( is_writable( $temp_dir ) && $dir = opendir( $temp_dir ) ) {
|
2392 |
while ( FALSE !== ( $file = readdir( $dir ) ) ) {
|
inc/class-jobtype-file.php
CHANGED
@@ -291,9 +291,9 @@ class BackWPup_JobType_File extends BackWPup_JobTypes {
|
|
291 |
<tr>
|
292 |
<th scope="row"><?php _e( 'Include special files', 'backwpup' ); ?></th>
|
293 |
<td>
|
294 |
-
<label for="idbackupspecialfiles"><input class="checkbox help-tip" id="idbackupspecialfiles" title="<?php _e( 'If the WordPress root folder is not included in this backup job, check this option to additionally include wp-config.php, robots.txt, .htaccess, .htpasswd and favicon.ico into the backup. Your wp-config.php will be included even if you placed it in the parent directory of your root folder.', 'backwpup' ); ?>"
|
295 |
type="checkbox"<?php checked( BackWPup_Option::get( $main, 'backupspecialfiles' ), TRUE, TRUE ); ?>
|
296 |
-
name="backupspecialfiles" value="1" /> <?php _e( 'Backup wp-config.php, robots.txt, .htaccess, .htpasswd and favicon.ico from root.', 'backwpup' ); ?></label>
|
297 |
</td>
|
298 |
</tr>
|
299 |
<tr>
|
@@ -512,6 +512,10 @@ class BackWPup_JobType_File extends BackWPup_JobTypes {
|
|
512 |
$job_object->additional_files_to_backup[ ] = $abs_path . '.htaccess';
|
513 |
$job_object->log( sprintf( __( 'Added "%s" to backup file list', 'backwpup' ), '.htaccess' ) );
|
514 |
}
|
|
|
|
|
|
|
|
|
515 |
if ( is_readable( $abs_path . '.htpasswd' ) && empty( $job_object->job[ 'backuproot' ] ) ) {
|
516 |
$job_object->additional_files_to_backup[ ] = $abs_path . '.htpasswd';
|
517 |
$job_object->log( sprintf( __( 'Added "%s" to backup file list', 'backwpup' ), '.htpasswd' ) );
|
291 |
<tr>
|
292 |
<th scope="row"><?php _e( 'Include special files', 'backwpup' ); ?></th>
|
293 |
<td>
|
294 |
+
<label for="idbackupspecialfiles"><input class="checkbox help-tip" id="idbackupspecialfiles" title="<?php _e( 'If the WordPress root folder is not included in this backup job, check this option to additionally include wp-config.php, robots.txt, .htaccess, nginx.conf, .htpasswd and favicon.ico into the backup. Your wp-config.php will be included even if you placed it in the parent directory of your root folder.', 'backwpup' ); ?>"
|
295 |
type="checkbox"<?php checked( BackWPup_Option::get( $main, 'backupspecialfiles' ), TRUE, TRUE ); ?>
|
296 |
+
name="backupspecialfiles" value="1" /> <?php _e( 'Backup wp-config.php, robots.txt, nginx.conf, .htaccess, .htpasswd and favicon.ico from root.', 'backwpup' ); ?></label>
|
297 |
</td>
|
298 |
</tr>
|
299 |
<tr>
|
512 |
$job_object->additional_files_to_backup[ ] = $abs_path . '.htaccess';
|
513 |
$job_object->log( sprintf( __( 'Added "%s" to backup file list', 'backwpup' ), '.htaccess' ) );
|
514 |
}
|
515 |
+
if ( is_readable( $abs_path . 'nginx.conf' ) && empty( $job_object->job[ 'backuproot' ] ) ) {
|
516 |
+
$job_object->additional_files_to_backup[ ] = $abs_path . 'nginx.conf';
|
517 |
+
$job_object->log( sprintf( __( 'Added "%s" to backup file list', 'backwpup' ), 'nginx.conf' ) );
|
518 |
+
}
|
519 |
if ( is_readable( $abs_path . '.htpasswd' ) && empty( $job_object->job[ 'backuproot' ] ) ) {
|
520 |
$job_object->additional_files_to_backup[ ] = $abs_path . '.htpasswd';
|
521 |
$job_object->log( sprintf( __( 'Added "%s" to backup file list', 'backwpup' ), '.htpasswd' ) );
|
inc/class-jobtype-wpexp.php
CHANGED
@@ -305,7 +305,6 @@ class BackWPup_JobType_WPEXP extends BackWPup_JobTypes {
|
|
305 |
|
306 |
// fetch 20 posts at a time rather than loading the entire table into memory
|
307 |
while ( $next_posts = array_splice( $job_object->steps_data[ $job_object->step_working ]['post_ids'], 0, 20 ) ) {
|
308 |
-
wp_cache_flush();
|
309 |
$where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')';
|
310 |
$posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" );
|
311 |
$wxr_post = '';
|
@@ -394,7 +393,7 @@ class BackWPup_JobType_WPEXP extends BackWPup_JobTypes {
|
|
394 |
$job_object->do_restart_time();
|
395 |
}
|
396 |
|
397 |
-
remove_filter( 'wxr_export_skip_postmeta', array( $this, 'wxr_filter_postmeta' ), 10
|
398 |
|
399 |
if ( $job_object->steps_data[ $job_object->step_working ]['substep'] == 'check' ) {
|
400 |
|
@@ -515,8 +514,9 @@ class BackWPup_JobType_WPEXP extends BackWPup_JobTypes {
|
|
515 |
* @return string
|
516 |
*/
|
517 |
private function wxr_cdata( $str ) {
|
518 |
-
if ( seems_utf8( $str )
|
519 |
$str = utf8_encode( $str );
|
|
|
520 |
|
521 |
// not allowed UTF-8 chars in XML
|
522 |
$str = preg_replace( '/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', '', $str );
|
@@ -637,8 +637,10 @@ class BackWPup_JobType_WPEXP extends BackWPup_JobTypes {
|
|
637 |
* Output list of authors with posts
|
638 |
*
|
639 |
* @since WordPress 3.1.0
|
|
|
|
|
640 |
*/
|
641 |
-
private function wxr_authors_list() {
|
642 |
global $wpdb;
|
643 |
|
644 |
$authors = array();
|
@@ -691,7 +693,7 @@ class BackWPup_JobType_WPEXP extends BackWPup_JobTypes {
|
|
691 |
* @since WordPress 2.3.0
|
692 |
*/
|
693 |
private function wxr_post_taxonomy() {
|
694 |
-
|
695 |
|
696 |
$taxonomies = get_object_taxonomies( $post->post_type );
|
697 |
if ( empty( $taxonomies ) )
|
305 |
|
306 |
// fetch 20 posts at a time rather than loading the entire table into memory
|
307 |
while ( $next_posts = array_splice( $job_object->steps_data[ $job_object->step_working ]['post_ids'], 0, 20 ) ) {
|
|
|
308 |
$where = 'WHERE ID IN (' . join( ',', $next_posts ) . ')';
|
309 |
$posts = $wpdb->get_results( "SELECT * FROM {$wpdb->posts} $where" );
|
310 |
$wxr_post = '';
|
393 |
$job_object->do_restart_time();
|
394 |
}
|
395 |
|
396 |
+
remove_filter( 'wxr_export_skip_postmeta', array( $this, 'wxr_filter_postmeta' ), 10 );
|
397 |
|
398 |
if ( $job_object->steps_data[ $job_object->step_working ]['substep'] == 'check' ) {
|
399 |
|
514 |
* @return string
|
515 |
*/
|
516 |
private function wxr_cdata( $str ) {
|
517 |
+
if ( ! seems_utf8( $str ) ) {
|
518 |
$str = utf8_encode( $str );
|
519 |
+
}
|
520 |
|
521 |
// not allowed UTF-8 chars in XML
|
522 |
$str = preg_replace( '/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', '', $str );
|
637 |
* Output list of authors with posts
|
638 |
*
|
639 |
* @since WordPress 3.1.0
|
640 |
+
*
|
641 |
+
* @return string
|
642 |
*/
|
643 |
+
private function wxr_authors_list( ) {
|
644 |
global $wpdb;
|
645 |
|
646 |
$authors = array();
|
693 |
* @since WordPress 2.3.0
|
694 |
*/
|
695 |
private function wxr_post_taxonomy() {
|
696 |
+
$post = get_post();
|
697 |
|
698 |
$taxonomies = get_object_taxonomies( $post->post_type );
|
699 |
if ( empty( $taxonomies ) )
|
inc/class-mysqldump.php
CHANGED
@@ -102,7 +102,7 @@ class BackWPup_MySQLDump {
|
|
102 |
|
103 |
|
104 |
if ( ! $this->mysqli->options( MYSQLI_OPT_CONNECT_TIMEOUT, 5 ) ) {
|
105 |
-
|
106 |
}
|
107 |
|
108 |
//connect to Database
|
@@ -114,7 +114,7 @@ class BackWPup_MySQLDump {
|
|
114 |
if ( ! empty( $args[ 'dbcharset' ] ) && method_exists( $this->mysqli, 'set_charset' ) ) {
|
115 |
$res = $this->mysqli->set_charset( $args[ 'dbcharset' ] );
|
116 |
if ( ! $res ) {
|
117 |
-
|
118 |
}
|
119 |
}
|
120 |
|
@@ -306,6 +306,30 @@ class BackWPup_MySQLDump {
|
|
306 |
$res->close();
|
307 |
}
|
308 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
309 |
//for better import with mysql client
|
310 |
$dbdumpfooter = "\n/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;\n";
|
311 |
$dbdumpfooter .= "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;\n";
|
102 |
|
103 |
|
104 |
if ( ! $this->mysqli->options( MYSQLI_OPT_CONNECT_TIMEOUT, 5 ) ) {
|
105 |
+
trigger_error( __( 'Setting of MySQLi connection timeout failed', 'backwpup' ) );
|
106 |
}
|
107 |
|
108 |
//connect to Database
|
114 |
if ( ! empty( $args[ 'dbcharset' ] ) && method_exists( $this->mysqli, 'set_charset' ) ) {
|
115 |
$res = $this->mysqli->set_charset( $args[ 'dbcharset' ] );
|
116 |
if ( ! $res ) {
|
117 |
+
trigger_error( sprintf( _x( 'Cannot set DB charset to %s error: %s','Database Charset', 'backwpup' ), $args[ 'dbcharset' ], $this->mysqli->error ), E_USER_WARNING );
|
118 |
}
|
119 |
}
|
120 |
|
306 |
$res->close();
|
307 |
}
|
308 |
|
309 |
+
//dump Trigger
|
310 |
+
$res = $this->mysqli->query( "SHOW TRIGGERS FROM `" . $this->dbname . "`" );
|
311 |
+
$GLOBALS[ 'wpdb' ]->num_queries ++;
|
312 |
+
if ( $this->mysqli->error ) {
|
313 |
+
trigger_error( sprintf( __( 'Database error %1$s for query %2$s', 'backwpup' ), $this->mysqli->error, "SHOW TRIGGERS" ), E_USER_WARNING );
|
314 |
+
} else {
|
315 |
+
while ( $triggers = $res->fetch_assoc() ) {
|
316 |
+
$create = "\n--\n-- Trigger structure for " . $triggers[ 'Trigger' ] . "\n--\n\n";
|
317 |
+
$create .= "DROP TRIGGER IF EXISTS `" . $triggers[ 'Trigger' ] . "`;\n";
|
318 |
+
$create .= "DELIMITER //\n";
|
319 |
+
$res2 = $this->mysqli->query( "SHOW CREATE TRIGGER `" . $this->dbname . "`.`" . $triggers[ 'Trigger' ] . "`" );
|
320 |
+
$GLOBALS[ 'wpdb' ]->num_queries ++;
|
321 |
+
if ( $this->mysqli->error ) {
|
322 |
+
trigger_error( sprintf( __( 'Database error %1$s for query %2$s', 'backwpup' ), $this->mysqli->error, "SHOW CREATE TRIGGER `" . $this->dbname . "`.`" . $triggers[ 'Trigger' ] . "`" ), E_USER_WARNING );
|
323 |
+
}
|
324 |
+
$create_trigger = $res2->fetch_assoc();
|
325 |
+
$res2->close();
|
326 |
+
$create .= $create_trigger[ 'SQL Original Statement' ] . ";\n";
|
327 |
+
$create .= "//\nDELIMITER ;\n";
|
328 |
+
$this->write( $create );
|
329 |
+
}
|
330 |
+
$res->close();
|
331 |
+
}
|
332 |
+
|
333 |
//for better import with mysql client
|
334 |
$dbdumpfooter = "\n/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;\n";
|
335 |
$dbdumpfooter .= "/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;\n";
|
inc/class-page-editjob.php
CHANGED
@@ -422,11 +422,12 @@ class BackWPup_Page_Editjob {
|
|
422 |
echo '</h2>';
|
423 |
//display messages
|
424 |
BackWPup_Admin::display_messages();
|
425 |
-
echo '<form name="editjob" id="editjob" method="post" action="' . admin_url( 'admin-post.php
|
426 |
echo '<input type="hidden" id="jobid" name="jobid" value="' . $jobid . '" />';
|
427 |
echo '<input type="hidden" name="tab" value="' . $_GET[ 'tab' ] . '" />';
|
428 |
echo '<input type="hidden" name="nexttab" value="' . $_GET[ 'tab' ] . '" />';
|
429 |
echo '<input type="hidden" name="page" value="backwpupeditjob" />';
|
|
|
430 |
echo '<input type="hidden" name="anchor" value="" />';
|
431 |
wp_nonce_field( 'backwpupeditjob_page' );
|
432 |
wp_nonce_field( 'backwpup_ajax_nonce', 'backwpupajaxnonce', FALSE );
|
422 |
echo '</h2>';
|
423 |
//display messages
|
424 |
BackWPup_Admin::display_messages();
|
425 |
+
echo '<form name="editjob" id="editjob" method="post" action="' . admin_url( 'admin-post.php' ) . '">';
|
426 |
echo '<input type="hidden" id="jobid" name="jobid" value="' . $jobid . '" />';
|
427 |
echo '<input type="hidden" name="tab" value="' . $_GET[ 'tab' ] . '" />';
|
428 |
echo '<input type="hidden" name="nexttab" value="' . $_GET[ 'tab' ] . '" />';
|
429 |
echo '<input type="hidden" name="page" value="backwpupeditjob" />';
|
430 |
+
echo '<input type="hidden" name="action" value="backwpup" />';
|
431 |
echo '<input type="hidden" name="anchor" value="" />';
|
432 |
wp_nonce_field( 'backwpupeditjob_page' );
|
433 |
wp_nonce_field( 'backwpup_ajax_nonce', 'backwpupajaxnonce', FALSE );
|
inc/class-page-jobs.php
CHANGED
@@ -445,9 +445,15 @@ class BackWPup_Page_Jobs extends WP_List_Table {
|
|
445 |
if ( $response_code < 200 && $response_code > 204 ) {
|
446 |
$test_result .= sprintf( __( 'The HTTP response test get a false http status (%s)','backwpup' ), wp_remote_retrieve_response_code( $raw_response ) );
|
447 |
} else {
|
448 |
-
$
|
449 |
-
|
450 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
451 |
}
|
452 |
}
|
453 |
if ( ! empty( $test_result ) ) {
|
445 |
if ( $response_code < 200 && $response_code > 204 ) {
|
446 |
$test_result .= sprintf( __( 'The HTTP response test get a false http status (%s)','backwpup' ), wp_remote_retrieve_response_code( $raw_response ) );
|
447 |
} else {
|
448 |
+
$response_header = wp_remote_retrieve_header( $raw_response, 'x-backwpup-version' );
|
449 |
+
$version = BackWPup::get_plugin_data( 'version' );
|
450 |
+
if ( $response_header !== $version ) {
|
451 |
+
$headers = '<br>';
|
452 |
+
$response_headers = wp_remote_retrieve_headers( $raw_response );
|
453 |
+
foreach( $response_headers as $key => $value ) {
|
454 |
+
$headers .= esc_attr( $key ) . ': ' . esc_attr( $value ) . '<br>';
|
455 |
+
}
|
456 |
+
$test_result .= sprintf( __( '<strong>Missing or not expected HTTP response headers:</strong> %s','backwpup' ), $headers );
|
457 |
}
|
458 |
}
|
459 |
if ( ! empty( $test_result ) ) {
|
inc/class-page-settings.php
CHANGED
@@ -127,9 +127,10 @@ class BackWPup_Page_Settings {
|
|
127 |
BackWPup_Admin::display_messages();
|
128 |
?>
|
129 |
|
130 |
-
<form id="settingsform" action="<?php echo admin_url( 'admin-post.php
|
131 |
<?php wp_nonce_field( 'backwpupsettings_page' ); ?>
|
132 |
<input type="hidden" name="page" value="backwpupsettings" />
|
|
|
133 |
<input type="hidden" name="anchor" value="#backwpup-tab-general" />
|
134 |
|
135 |
<div class="table ui-tabs-hide" id="backwpup-tab-general">
|
@@ -439,9 +440,15 @@ class BackWPup_Page_Settings {
|
|
439 |
$test_result .= sprintf( __( 'The HTTP response test get an error "%s"','backwpup' ), $raw_response->get_error_message() );
|
440 |
elseif ( 200 != wp_remote_retrieve_response_code( $raw_response ) && 204 != wp_remote_retrieve_response_code( $raw_response ) )
|
441 |
$test_result .= sprintf( __( 'The HTTP response test get a false http status (%s)','backwpup' ), wp_remote_retrieve_response_code( $raw_response ) );
|
442 |
-
$
|
443 |
-
if (
|
444 |
-
$
|
|
|
|
|
|
|
|
|
|
|
|
|
445 |
|
446 |
if ( empty( $test_result ) )
|
447 |
_e( 'Response Test O.K.', 'backwpup' );
|
127 |
BackWPup_Admin::display_messages();
|
128 |
?>
|
129 |
|
130 |
+
<form id="settingsform" action="<?php echo admin_url( 'admin-post.php' ); ?>" method="post">
|
131 |
<?php wp_nonce_field( 'backwpupsettings_page' ); ?>
|
132 |
<input type="hidden" name="page" value="backwpupsettings" />
|
133 |
+
<input type="hidden" name="action" value="backwpup" />
|
134 |
<input type="hidden" name="anchor" value="#backwpup-tab-general" />
|
135 |
|
136 |
<div class="table ui-tabs-hide" id="backwpup-tab-general">
|
440 |
$test_result .= sprintf( __( 'The HTTP response test get an error "%s"','backwpup' ), $raw_response->get_error_message() );
|
441 |
elseif ( 200 != wp_remote_retrieve_response_code( $raw_response ) && 204 != wp_remote_retrieve_response_code( $raw_response ) )
|
442 |
$test_result .= sprintf( __( 'The HTTP response test get a false http status (%s)','backwpup' ), wp_remote_retrieve_response_code( $raw_response ) );
|
443 |
+
$header = wp_remote_retrieve_header( $raw_response, 'x-backwpup-version' );
|
444 |
+
if ( $header !== BackWPup::get_plugin_data( 'version' ) ) {
|
445 |
+
$headers = '<br>';
|
446 |
+
$response_headers = wp_remote_retrieve_headers( $raw_response );
|
447 |
+
foreach( $response_headers as $key => $value ) {
|
448 |
+
$headers .= esc_attr( $key ) . ': ' . esc_attr( $value ) . '<br>';
|
449 |
+
}
|
450 |
+
$test_result .= sprintf( __( '<strong>Missing or not expected HTTP response headers:</strong> %s','backwpup' ), $headers );
|
451 |
+
}
|
452 |
|
453 |
if ( empty( $test_result ) )
|
454 |
_e( 'Response Test O.K.', 'backwpup' );
|
readme.txt
CHANGED
@@ -3,7 +3,7 @@ Contributors: inpsyde, danielhuesken, Bueltge, nullbyte
|
|
3 |
Tags: Amazon, Amazon S3, back up, backup, chinese, cloud, cloud files, database, db backup, dropbox, dump, file, french, ftp, ftps, german, migrate, multisite, russian, schedule, sftp, storage, S3, time, upload, xml
|
4 |
Requires at least: 3.8
|
5 |
Tested up to: 4.4.1
|
6 |
-
Stable tag: 3.2.
|
7 |
License: GPLv3
|
8 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
9 |
|
@@ -170,6 +170,12 @@ Please check all settings after the update:
|
|
170 |
|
171 |
|
172 |
== Changelog ==
|
|
|
|
|
|
|
|
|
|
|
|
|
173 |
= Version 3.2.3 =
|
174 |
* Added: AWS Region Asien-Pazifik (Seoul)
|
175 |
* Improved: open basedir checking
|
3 |
Tags: Amazon, Amazon S3, back up, backup, chinese, cloud, cloud files, database, db backup, dropbox, dump, file, french, ftp, ftps, german, migrate, multisite, russian, schedule, sftp, storage, S3, time, upload, xml
|
4 |
Requires at least: 3.8
|
5 |
Tested up to: 4.4.1
|
6 |
+
Stable tag: 3.2.4
|
7 |
License: GPLv3
|
8 |
License URI: http://www.gnu.org/licenses/gpl-3.0.html
|
9 |
|
170 |
|
171 |
|
172 |
== Changelog ==
|
173 |
+
= Version 3.2.4 =
|
174 |
+
* Added: Backup database triggers
|
175 |
+
* Fixed: Charset issues on file names in archives
|
176 |
+
* Improved: checking on response test
|
177 |
+
* Changed: Dropbox API URLs
|
178 |
+
|
179 |
= Version 3.2.3 =
|
180 |
* Added: AWS Region Asien-Pazifik (Seoul)
|
181 |
* Improved: open basedir checking
|