PluginProbe
UpdraftPlus: WP Backup & Migration Plugin / 1.8.13
UpdraftPlus: WP Backup & Migration Plugin v1.8.13
1.26.7 1.26.6 1.26.5 1.26.4 1.26.3 1.9.19 1.9.25 1.9.26 1.9.30 1.9.31 1.9.32 1.9.4 1.9.40 1.9.41 1.9.42 1.9.43 1.9.44 1.9.45 1.9.46 1.9.5 1.9.50 1.9.51 1.9.60 1.9.62 1.9.63 All 371 releases
updraftplus / methods / googledrive.php

googledrive.php in UpdraftPlus: WP Backup & Migration Plugin 1.8.13, at methods/googledrive.php

497 lines 24.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class UpdraftPlus_BackupModule_googledrive {
4
5 private $gdocs;
6
7 public function action_auth() {
8 if ( isset( $_GET['state'] ) ) {
9 if ('success' == $_GET['state']) {
10 add_action('all_admin_notices', array('UpdraftPlus_BackupModule_googledrive', 'show_authed_admin_success') );
11 }
12 elseif ('token' == $_GET['state']) $this->gdrive_auth_token();
13 elseif ('revoke' == $_GET['state']) $this->gdrive_auth_revoke();
14 } elseif (isset($_GET['updraftplus_googleauth'])) {
15 $this->gdrive_auth_request();
16 }
17 }
18
19 // Get a Google account access token using the refresh token
20 private function access_token($token, $client_id, $client_secret) {
21
22 global $updraftplus;
23 $updraftplus->log("Google Drive: requesting access token: client_id=$client_id");
24
25 $query_body = array(
26 'refresh_token' => $token,
27 'client_id' => $client_id,
28 'client_secret' => $client_secret,
29 'grant_type' => 'refresh_token'
30 );
31
32 $result = wp_remote_post('https://accounts.google.com/o/oauth2/token', array('timeout' => '15', 'method' => 'POST', 'body' => $query_body) );
33
34 if (is_wp_error($result)) {
35 $updraftplus->log("Google Drive error when requesting access token");
36 foreach ($result->get_error_messages() as $msg) $updraftplus->log("Error message: $msg");
37 return false;
38 } else {
39 $json_values = json_decode( $result['body'], true );
40 if ( isset( $json_values['access_token'] ) ) {
41 $updraftplus->log("Google Drive: successfully obtained access token");
42 return $json_values['access_token'];
43 } else {
44 $updraftplus->log("Google Drive error when requesting access token: response does not contain access_token");
45 return false;
46 }
47 }
48 }
49
50 // Acquire single-use authorization code from Google OAuth 2.0
51 public function gdrive_auth_request() {
52 // First, revoke any existing token, since Google doesn't appear to like issuing new ones
53 if (UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') != "") $this->gdrive_auth_revoke();
54 // We use 'force' here for the approval_prompt, not 'auto', as that deals better with messy situations where the user authenticated, then changed settings
55 $params = array(
56 'response_type' => 'code',
57 'client_id' => UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'),
58 'redirect_uri' => UpdraftPlus_Options::admin_page_url().'?action=updraftmethod-googledrive-auth',
59 'scope' => 'https://www.googleapis.com/auth/drive https://www.googleapis.com/auth/drive.file https://docs.google.com/feeds/ https://docs.googleusercontent.com/ https://spreadsheets.google.com/feeds/',
60 'state' => 'token',
61 'access_type' => 'offline',
62 'approval_prompt' => 'force'
63 );
64 if(headers_sent()) {
65 global $updraftplus;
66 $updraftplus->log(sprintf(__('The %s authentication could not go ahead, because something else on your site is breaking it. Try disabling your other plugins and switching to a default theme. (Specifically, you are looking for the component that sends output (most likely PHP warnings/errors) before the page begins. Turning off any debugging settings may also help).', ''), 'Google Drive'), 'error');
67 } else {
68 header('Location: https://accounts.google.com/o/oauth2/auth?'.http_build_query($params));
69 }
70 }
71
72 // Revoke a Google account refresh token
73 // Returns the parameter fed in, so can be used as a WordPress options filter
74 public function gdrive_auth_revoke() {
75 $ignore = wp_remote_get('https://accounts.google.com/o/oauth2/revoke?token='.UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'));
76 UpdraftPlus_Options::update_updraft_option('updraft_googledrive_token','');
77 }
78
79 // Get a Google account refresh token using the code received from gdrive_auth_request
80 public function gdrive_auth_token() {
81 if( isset( $_GET['code'] ) ) {
82 $post_vars = array(
83 'code' => $_GET['code'],
84 'client_id' => UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'),
85 'client_secret' => UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret'),
86 'redirect_uri' => UpdraftPlus_Options::admin_page_url().'?action=updraftmethod-googledrive-auth',
87 'grant_type' => 'authorization_code'
88 );
89
90 $result = wp_remote_post('https://accounts.google.com/o/oauth2/token', array('timeout' => 30, 'method' => 'POST', 'body' => $post_vars) );
91
92 if (is_wp_error($result)) {
93 $add_to_url = "Bad response when contacting Google: ";
94 foreach ( $result->get_error_messages() as $message ) {
95 global $updraftplus;
96 $updraftplus->log("Google Drive authentication error: ".$message);
97 $add_to_url .= $message.". ";
98 }
99 header('Location: '.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&error='.urlencode($add_to_url));
100 } else {
101 $json_values = json_decode( $result['body'], true );
102 if ( isset( $json_values['refresh_token'] ) ) {
103
104 // Save token
105 UpdraftPlus_Options::update_updraft_option('updraft_googledrive_token', $json_values['refresh_token']);
106
107 if ( isset($json_values['access_token'])) {
108
109 UpdraftPlus_Options::update_updraft_option('updraftplus_tmp_googledrive_access_token', $json_values['access_token']);
110
111 // We do this to clear the GET parameters, otherwise WordPress sticks them in the _wp_referer in the form and brings them back, leading to confusion + errors
112 header('Location: '.UpdraftPlus_Options::admin_page_url().'?action=updraftmethod-googledrive-auth&page=updraftplus&state=success');
113
114 }
115
116 } else {
117
118 $msg = __( 'No refresh token was received from Google. This often means that you entered your client secret wrongly, or that you have not yet re-authenticated (below) since correcting it. Re-check it, then follow the link to authenticate again. Finally, if that does not work, then use expert mode to wipe all your settings, create a new Google client ID/secret, and start again.', 'updraftplus' );
119
120 if (isset($json_values['error'])) $msg .= ' '.sprintf(__('Error: %s', 'updraftplus'), $json_values['error']);
121
122 header('Location: '.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&error='.urlencode($msg));
123 }
124 }
125 }
126 else {
127 header('Location: '.UpdraftPlus_Options::admin_page_url().'?page=updraftplus&error='.urlencode(__( 'Authorization failed', 'updraftplus')));
128 }
129 }
130
131 public function show_authed_admin_success() {
132
133 global $updraftplus_admin;
134
135 $updraftplus_tmp_access_token = UpdraftPlus_Options::get_updraft_option('updraftplus_tmp_googledrive_access_token');
136 if (empty($updraftplus_tmp_access_token)) return;
137
138 $message = '';
139 try {
140 if( !class_exists('UpdraftPlus_GDocs')) require_once(UPDRAFTPLUS_DIR.'/includes/class-gdocs.php');
141 $x = new UpdraftPlus_BackupModule_googledrive;
142 if ( !is_wp_error( $e = $x->need_gdocs($updraftplus_tmp_access_token) ) ) {
143 $quota_total = max($x->gdocs->get_quota_total(), 1);
144 $quota_used = $x->gdocs->get_quota_used();
145 if (is_numeric($quota_total) && is_numeric($quota_used)) {
146 $available_quota = $quota_total - $quota_used;
147 $used_perc = round($quota_used*100/$quota_total, 1);
148 $message .= sprintf(__('Your %s quota usage: %s %% used, %s available','updraftplus'), 'Google Drive', $used_perc, round($available_quota/1048576, 1).' Mb');
149 }
150 }
151 } catch (Exception $e) {
152 }
153
154 $updraftplus_admin->show_admin_warning(__('Success','updraftplus').': '.sprintf(__('you have authenticated your %s account.','updraftplus'),__('Google Drive','updraftplus')).' '.$message);
155
156 UpdraftPlus_Options::delete_updraft_option('updraftplus_tmp_googledrive_access_token');
157
158 }
159
160 // This function just does the formalities, and off-loads the main work to upload_file
161 public function backup($backup_array) {
162
163 global $updraftplus, $updraftplus_backup;
164
165 if( !class_exists('UpdraftPlus_GDocs')) require_once(UPDRAFTPLUS_DIR.'/includes/class-gdocs.php');
166
167 // Do we have an access token?
168 if ( !$access_token = $this->access_token( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') )) {
169 $updraftplus->log('ERROR: Have not yet obtained an access token from Google (has the user authorised?)');
170 $updraftplus->log(__('Have not yet obtained an access token from Google - you need to authorise or re-authorise your connection to Google Drive.','updraftplus'), 'error');
171 return new WP_Error( "no_access_token", __("Have not yet obtained an access token from Google (has the user authorised?)",'updraftplus'));
172 }
173
174 $updraft_dir = trailingslashit($updraftplus->backups_dir_location());
175
176 // Make sure $this->gdocs is a UpdraftPlus_GDocs object, or give an error
177 if ( is_wp_error( $e = $this->need_gdocs($access_token) ) ) return false;
178 $gdocs_object = $this->gdocs;
179
180 foreach ($backup_array as $file) {
181
182 $available_quota = -1;
183
184 try {
185 $quota_total = $gdocs_object->get_quota_total();
186 $quota_used = $gdocs_object->get_quota_used();
187 $available_quota = $quota_total - $quota_used;
188 $message = "Google Drive quota usage: used=".round($quota_used/1048576,1)." Mb, total=".round($quota_total/1048576,1)." Mb, available=".round($available_quota/1048576,1)." Mb";
189 $updraftplus->log($message);
190 } catch (Exception $e) {
191 $updraftplus->log("Google Drive quota usage: failed to obtain this information: ".$e->getMessage());
192 }
193
194 $file_path = $updraft_dir.$file;
195 $file_name = basename($file_path);
196 $updraftplus->log("$file_name: Attempting to upload to Google Drive");
197
198 $filesize = filesize($file_path);
199 $already_failed = false;
200 if ($available_quota != -1) {
201 if ($filesize > $available_quota) {
202 $already_failed = true;
203 $updraftplus->log("File upload expected to fail: file ($file_name) size is $filesize b, whereas available quota is only $available_quota b");
204 $updraftplus->log(sprintf(__("Account full: your %s account has only %d bytes left, but the file to be uploaded is %d bytes",'updraftplus'),__('Google Drive', 'updraftplus'), $available_quota, $filesize), 'error');
205 }
206 }
207 if (!$already_failed && $filesize > 10737418240) {
208 # 10Gb
209 $updraftplus->log("File upload expected to fail: file ($file_name) size is $filesize b (".round($filesize/1073741824, 4)." Gb), whereas Google Drive's limit is 10Gb (1073741824 bytes)");
210 $updraftplus->log(sprintf(__("Upload expected to fail: the %s limit for any single file is %s, whereas this file is %s Gb (%d bytes)",'updraftplus'),__('Google Drive', 'updraftplus'), '10Gb (1073741824)', round($filesize/1073741824, 4), $filesize), 'warning');
211 }
212
213 $timer_start = microtime(true);
214 if ( $id = $this->upload_file( $file_path, $file_name, UpdraftPlus_Options::get_updraft_option('updraft_googledrive_remotepath')) ) {
215 $updraftplus->log('OK: Archive ' . $file_name . ' uploaded to Google Drive in ' . ( round(microtime( true ) - $timer_start,2) ) . ' seconds (id: '.$id.')' );
216 $updraftplus->uploaded_file($file, $id);
217 } else {
218 $updraftplus->log("ERROR: $file_name: Failed to upload to Google Drive" );
219 $updraftplus->log("$file_name: ".sprintf(__('Failed to upload to %s','updraftplus'),__('Google Drive','updraftplus')), 'error');
220 }
221 }
222
223 return null;
224 }
225
226 public function delete($files) {
227 global $updraftplus;
228 if (is_string($files)) $files=array($files);
229
230 if ( !$this->is_gdocs($this->gdocs) ) {
231
232 // Do we have an access token?
233 if ( !$access_token = $this->access_token( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') )) {
234 $updraftplus->log('ERROR: Have not yet obtained an access token from Google (has the user authorised?)');
235 $updraftplus->log(__('Have not yet obtained an access token from Google - you need to authorise or re-authorise your connection to Google Drive.','updraftplus'), 'error');
236 return false;
237 }
238
239 // Make sure $this->gdocs is a UpdraftPlus_GDocs object, or give an error
240 if ( is_wp_error( $e = $this->need_gdocs($access_token) ) ) return false;
241
242 }
243
244 $ids = UpdraftPlus_Options::get_updraft_option('updraft_file_ids', array());
245
246 $ret = true;
247
248 foreach ($files as $file) {
249
250 if (!isset($ids[$file])) {
251 $updraftplus->log("$file: Could not delete: could not find a record of the Google Drive file ID for this file");
252 $ret = false;
253 continue;
254 }
255
256 $del = $this->gdocs->delete_resource($ids[$file]);
257 if (is_wp_error($del)) {
258 foreach ($del->get_error_messages() as $msg) $updraftplus->log("$file: Deletion failed: $msg");
259 $ret = false;
260 continue;
261 } else {
262 $updraftplus->log("$file: Deletion successful");
263 unset($ids[$file]);
264 UpdraftPlus_Options::update_updraft_option('updraft_file_ids', $ids);
265 }
266
267 }
268
269 return $ret;
270
271
272 }
273
274 // Returns:
275 // true = already uploaded
276 // false = failure
277 // otherwise, the file ID
278 private function upload_file( $file, $title, $parent = '') {
279
280 global $updraftplus;
281
282 $gdocs_object = $this->gdocs;
283
284 $hash = md5($file);
285 $transkey = 'upd_'.$hash.'_gloc';
286 // This is unset upon completion, so if it is set then we are resuming
287 $possible_location = $updraftplus->jobdata_get($transkey);
288
289 if ( empty( $possible_location ) ) {
290 $updraftplus->log(basename($file).": Attempting to upload file to Google Drive.");
291 $location = $gdocs_object->prepare_upload( $file, $title, $parent );
292 } else {
293 $updraftplus->log(basename($file).": Attempting to resume upload.");
294 $location = $gdocs_object->resume_upload( $file, $possible_location );
295 }
296
297 if ( is_wp_error( $location ) ) {
298 $updraftplus->log("GoogleDrive upload: an error occurred");
299 foreach ($location->get_error_messages() as $msg) {
300 $updraftplus->log("Error details: ".$msg);
301 $updraftplus->log(sprintf(__('Error: %s','updraftplus'), $msg), 'error');
302 }
303 return false;
304 }
305
306 if (!is_string($location) && true == $location) {
307 $updraftplus->log("$file: this file is already uploaded");
308 return true;
309 }
310
311 if ( is_string( $location ) ) {
312 $res = $location;
313 $updraftplus->log("Uploading file with title ".$title);
314 $d = 0;
315 // This counter is only used for when deciding what to log
316 $counter = 0;
317 do {
318 $log_string = ($counter == 0) ? "URL: $res" : "";
319 $updraftplus->record_uploaded_chunk($d, $log_string, $file);
320
321 $counter++; if ($counter >= 20) $counter=0;
322
323 $res = $gdocs_object->upload_chunk();
324 if (is_string($res)) $updraftplus->jobdata_set($transkey, $res);
325 $p = $gdocs_object->get_upload_percentage();
326 if ( $p - $d >= 1 ) {
327 $b = intval( $p - $d );
328 // echo '<span style="width:' . $b . '%"></span>';
329 $d += $b;
330 }
331 // $this->options['backup_list'][$id]['speed'] = $this->gdocs->get_upload_speed();
332 } while ( is_string( $res ) );
333 // echo '</div>';
334
335 if ( is_wp_error( $res ) || $res !== true) {
336 $updraftplus->log( "An error occurred during Google Drive upload (2)" );
337 $updraftplus->log(sprintf(__("An error occurred during %s upload (see log for more details)",'updraftplus'), 'Google Drive'), 'error');
338 if (is_wp_error( $res )) {
339 foreach ($res->get_error_messages() as $msg) $updraftplus->log($msg);
340 }
341 return false;
342 }
343
344 $updraftplus->log("The file was successfully uploaded to Google Drive in ".number_format_i18n( $gdocs_object->time_taken(), 3)." seconds at an upload speed of ".size_format( $gdocs_object->get_upload_speed() )."/s.");
345
346 $updraftplus->jobdata_delete($transkey);
347 // unset( $this->options['backup_list'][$id]['location'], $this->options['backup_list'][$id]['attempt'] );
348 }
349
350 return $gdocs_object->get_file_id();
351
352 // $this->update_quota();
353 // Google's "user info" service
354 // if ( empty( $this->options['user_info'] ) ) $this->set_user_info();
355
356 }
357
358 public function download($file) {
359
360 global $updraftplus;
361
362 if( !class_exists('UpdraftPlus_GDocs')) require_once(UPDRAFTPLUS_DIR.'/includes/class-gdocs.php');
363
364 // Do we have an access token?
365 if ( !$access_token = $this->access_token( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid'), UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') )) {
366 $updraftplus->log(__('Have not yet obtained an access token from Google (has the user authorised?)', 'updraftplus'), 'error');
367 return false;
368 }
369
370 // Make sure $this->gdocs is a UpdraftPlus_GDocs object, or give an error
371 if ( is_wp_error( $e = $this->need_gdocs($access_token) ) ) return false;
372 $gdocs_object = $this->gdocs;
373
374 $ids = UpdraftPlus_Options::get_updraft_option('updraft_file_ids', array());
375 if (!isset($ids[$file])) {
376 $updraftplus->log(sprintf(__("Google Drive error: %d: could not download: could not find a record of the Google Drive file ID for this file",'updraftplus'),$file), 'error');
377 return false;
378 } else {
379 $content_link = $gdocs_object->get_content_link( $ids[$file], $file );
380 if (is_wp_error($content_link)) {
381 $updraftplus->log(sprintf(__("Could not find %s in order to download it", 'updraftplus'),$file)." (id: ".$ids[$file].")", 'error');
382 foreach ($content_link->get_error_messages() as $msg) $updraftplus->log($msg, 'error');
383 return false;
384 }
385 // Actually download the thing
386
387 $download_to = $updraftplus->backups_dir_location().'/'.$file;
388 $gdocs_object->download_data($content_link, $download_to, true);
389
390 if (filesize($download_to) > 0) {
391 return true;
392 } else {
393 $updraftplus->log('Google Drive error: zero-size file was downloaded');
394 $updraftplus->log(sprintf(__('%s error: zero-size file was downloaded','updraftplus'), __("Google Drive ",'updraftplus'),__("Google Drive ",'updraftplus')), 'error');
395 return false;
396 }
397
398 }
399 return false;
400 }
401
402 // This function modified from wordpress.org/extend/plugins/backup, by Sorin Iclanzan, under the GPLv3 or later at your choice
403 private function need_gdocs($access_token) {
404
405 global $updraftplus;
406
407 if ( ! $this->is_gdocs($this->gdocs) ) {
408 if ( UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token') == "" || UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid') == "" || UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret') == "" ) {
409 $updraftplus->log("GoogleDrive: this account is not authorised");
410 return new WP_Error( "not_authorized", __("Account is not authorized.",'updraftplus') );
411 }
412
413 if ( is_wp_error($access_token) ) return $access_token;
414
415 if( !class_exists('UpdraftPlus_GDocs')) require_once(UPDRAFTPLUS_DIR.'/includes/class-gdocs.php');
416 $this->gdocs = new UpdraftPlus_GDocs($access_token);
417 // We need to be able to upload at least one chunk within the timeout (at least, we have seen an error report where the failure to do this seemed to be the cause)
418 // If we assume a user has at least 16kb/s (we saw one user with as low as 22kb/s), and that their provider may allow them only 15s, then we have the following settings
419 $this->gdocs->set_option('chunk_size', 0.2 ); # 0.2Mb; change from default of 512Kb
420 $this->gdocs->set_option('request_timeout', 15 ); # Change from default of 5s
421 $this->gdocs->set_option('max_resume_attempts', 36 ); # Doesn't look like GDocs class actually uses this anyway
422 if (UpdraftPlus_Options::get_updraft_option('updraft_ssl_disableverify')) {
423 $this->gdocs->set_option('ssl_verify', false);
424 } else {
425 $this->gdocs->set_option('ssl_verify', true);
426 }
427 }
428 return true;
429 }
430
431 // This function taken from wordpress.org/extend/plugins/backup, by Sorin Iclanzan, under the GPLv3 or later at your choice
432 function is_gdocs($thing) {
433 if ( is_object( $thing ) && is_a( $thing, 'UpdraftPlus_GDocs' ) ) return true;
434 return false;
435 }
436
437 public function config_print() {
438 ?>
439 <tr class="updraftplusmethod googledrive">
440 <td><?php _e('Google Drive','updraftplus');?>:</td>
441 <td>
442 <img src="https://developers.google.com/drive/images/drive_logo.png" alt="<?php _e('Google Drive','updraftplus');?>">
443 <p><em><?php printf(__('%s is a great choice, because UpdraftPlus supports chunked uploads - no matter how big your site is, UpdraftPlus can upload it a little at a time, and not get thwarted by timeouts.','updraftplus'),'Google Drive');?></em></p>
444 </td>
445 </tr>
446
447 <tr class="updraftplusmethod googledrive">
448 <th></th>
449 <td>
450 <?php
451 global $updraftplus_admin;
452 if (!class_exists('SimpleXMLElement')) {
453 $updraftplus_admin->show_double_warning('<strong>'.__('Warning','updraftplus').':</strong> '.sprintf(__('Your web server\'s PHP installation does not included a required module (%s). Please contact your web hosting provider\'s support.', 'updraftplus'), 'SimpleXMLElement').' '.sprintf(__("UpdraftPlus's %s module <strong>requires</strong> %s. Please do not file any support requests; there is no alternative.",'updraftplus'),__('Google Drive', 'updraftplus'), 'SimpleXMLElement'), 'googledrive');
454 }
455 ?>
456
457 </td>
458 </tr>
459
460 <tr class="updraftplusmethod googledrive">
461 <th>Google Drive:</th>
462 <td>
463 <p><a href="http://updraftplus.com/support/configuring-google-drive-api-access-in-updraftplus/"><strong><?php _e('For longer help, including screenshots, follow this link. The description below is sufficient for more expert users.','updraftplus');?></strong></a></p>
464 <p><a href="https://code.google.com/apis/console/"><?php _e('Follow this link to your Google API Console, and there create a Client ID in the API Access section.','updraftplus');?></a> <?php _e("Select 'Web Application' as the application type.",'updraftplus');?></p><p><?php echo htmlspecialchars(__('You must add the following as the authorised redirect URI (under "More Options") when asked','updraftplus'));?>: <kbd><?php echo UpdraftPlus_Options::admin_page_url().'?action=updraftmethod-googledrive-auth'; ?></kbd> <?php _e('N.B. If you install UpdraftPlus on several WordPress sites, then you cannot re-use your client ID; you must create a new one from your Google API console for each site.','updraftplus');?>
465
466 <?php
467 if (!class_exists('SimpleXMLElement')) { echo "<b>",__('Warning','updraftplus').':</b> '.__("You do not have the SimpleXMLElement installed. Google Drive backups will <b>not</b> work until you do.",'updraftplus'); }
468 ?>
469 </p>
470 </td>
471 </tr>
472
473 <tr class="updraftplusmethod googledrive">
474 <th><?php echo __('Google Drive','updraftplus').' '.__('Client ID','updraftplus'); ?>:</th>
475 <td><input type="text" autocomplete="off" style="width:412px" name="updraft_googledrive_clientid" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_googledrive_clientid')) ?>" /><br><em><?php _e('If Google later shows you the message "invalid_client", then you did not enter a valid client ID here.','updraftplus');?></em></td>
476 </tr>
477 <tr class="updraftplusmethod googledrive">
478 <th><?php echo __('Google Drive','updraftplus').' '.__('Client Secret','updraftplus'); ?>:</th>
479 <td><input type="<?php echo apply_filters('updraftplus_admin_secret_field_type', 'text'); ?>" style="width:412px" name="updraft_googledrive_secret" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_googledrive_secret')); ?>" /></td>
480 </tr>
481 <tr class="updraftplusmethod googledrive">
482 <th><?php echo __('Google Drive','updraftplus').' '.__('Folder ID','updraftplus'); ?>:</th>
483 <td><input type="text" style="width:412px" name="updraft_googledrive_remotepath" value="<?php echo htmlspecialchars(UpdraftPlus_Options::get_updraft_option('updraft_googledrive_remotepath')); ?>" /> <em><?php _e("<strong>This is NOT a folder name</strong>. To get a folder's ID navigate to that folder in Google Drive in your web browser and copy the ID from your browser's address bar. It is the part that comes after <kbd>#folders/</kbd>. Leave empty to use your root folder.",'updraftplus');?></em></td>
484 </tr>
485 <tr class="updraftplusmethod googledrive">
486 <th><?php _e('Authenticate with Google');?>:</th>
487 <td><p><?php if ('' != UpdraftPlus_Options::get_updraft_option('updraft_googledrive_token')) echo __("<strong>(You appear to be already authenticated,</strong> though you can authenticate again to refresh your access if you've had a problem).",'updraftplus'); ?> <a href="<?php echo UpdraftPlus_Options::admin_page_url();?>?action=updraftmethod-googledrive-auth&page=updraftplus&updraftplus_googleauth=doit"><?php print __('<strong>After</strong> you have saved your settings (by clicking \'Save Changes\' below), then come back here once and click this link to complete authentication with Google.','updraftplus');?></a>
488 </p>
489 </td>
490 </tr>
491 <?php
492 }
493
494 }
495
496 ?>
497