InfiniteWP Client - Version 1.2.12

Version Description

  • Improvement: Backup process will only backup WordPress tables which have configured prefix in wp-config.php.
  • Improvement: Support for Google Drive for cloud backup addon.
  • Improvement: Minor improvements.
  • Fix: Bug fixes
Download this release

Release Info

Developer infinitewp
Plugin Icon 128x128 InfiniteWP Client
Version 1.2.12
Comparing to
See all releases

Code changes from version 1.2.11 to 1.2.12

Files changed (47) hide show
  1. addons/backup_repository/backup_repository.class.php +44 -3
  2. addons/comments/comments.class.php +1 -1
  3. addons/manage_users/user.class.php +2 -2
  4. addons/post_links/post.class.php +1 -1
  5. backup.class.php +394 -7
  6. helper.class.php +1 -1
  7. init.php +2 -2
  8. lib/Google/Auth/Abstract.php +41 -0
  9. lib/Google/Auth/AssertionCredentials.php +133 -0
  10. lib/Google/Auth/Exception.php +22 -0
  11. lib/Google/Auth/LoginTicket.php +69 -0
  12. lib/Google/Auth/OAuth2.php +587 -0
  13. lib/Google/Auth/Simple.php +92 -0
  14. lib/Google/Cache/Abstract.php +53 -0
  15. lib/Google/Cache/Apc.php +73 -0
  16. lib/Google/Cache/Exception.php +21 -0
  17. lib/Google/Cache/File.php +145 -0
  18. lib/Google/Cache/Memcache.php +137 -0
  19. lib/Google/Cache/Null.php +56 -0
  20. lib/Google/Client.php +608 -0
  21. lib/Google/Collection.php +94 -0
  22. lib/Google/Config.php +315 -0
  23. lib/Google/Exception.php +20 -0
  24. lib/Google/Http/Batch.php +143 -0
  25. lib/Google/Http/CacheParser.php +184 -0
  26. lib/Google/Http/MediaFileUpload.php +303 -0
  27. lib/Google/Http/REST.php +139 -0
  28. lib/Google/Http/Request.php +476 -0
  29. lib/Google/IO/Abstract.php +312 -0
  30. lib/Google/IO/Curl.php +135 -0
  31. lib/Google/IO/Exception.php +22 -0
  32. lib/Google/IO/Stream.php +182 -0
  33. lib/Google/IO/cacerts.pem +2183 -0
  34. lib/Google/Model.php +250 -0
  35. lib/Google/Service.php +39 -0
  36. lib/Google/Service/Drive.php +5732 -0
  37. lib/Google/Service/Exception.php +53 -0
  38. lib/Google/Service/Oauth2.php +412 -0
  39. lib/Google/Service/Resource.php +210 -0
  40. lib/Google/Signer/Abstract.php +29 -0
  41. lib/Google/Signer/P12.php +91 -0
  42. lib/Google/Utils.php +135 -0
  43. lib/Google/Utils/URITemplate.php +333 -0
  44. lib/Google/Verifier/Abstract.php +30 -0
  45. lib/Google/Verifier/Pem.php +74 -0
  46. plugins/cleanup/cleanup.php +3 -3
  47. readme.txt +7 -1
addons/backup_repository/backup_repository.class.php CHANGED
@@ -34,7 +34,6 @@ class IWP_MMB_Backup_Repository extends IWP_MMB_Backup
34
35
function backup_repository($args){
36
37
-
38
if (!empty($args))
39
extract($args);
40
@@ -54,7 +53,6 @@ class IWP_MMB_Backup_Repository extends IWP_MMB_Backup
54
$backup_file = $results[count($results) - 1]['server']['file_path'];
55
}
56
57
-
58
if ($backup_file && file_exists($backup_file)) {
59
//FTP, Amazon S3 or Dropbox
60
if (isset($account_info['iwp_ftp']) && !empty($account_info)) {
@@ -82,7 +80,50 @@ class IWP_MMB_Backup_Repository extends IWP_MMB_Backup
82
$return = $this->dropbox_backup($account_info['iwp_dropbox']);
83
$this->update_status($task_name, 'dropbox', true);
84
iwp_mmb_print_flush('Dropbox upload: End');
85
- }
86
87
if ($return == true && $del_host_file) {
88
@unlink($backup_file);
34
35
function backup_repository($args){
36
37
if (!empty($args))
38
extract($args);
39
53
$backup_file = $results[count($results) - 1]['server']['file_path'];
54
}
55
56
if ($backup_file && file_exists($backup_file)) {
57
//FTP, Amazon S3 or Dropbox
58
if (isset($account_info['iwp_ftp']) && !empty($account_info)) {
80
$return = $this->dropbox_backup($account_info['iwp_dropbox']);
81
$this->update_status($task_name, 'dropbox', true);
82
iwp_mmb_print_flush('Dropbox upload: End');
83
+ }
84
+
85
+ if (isset($account_info['iwp_gdrive']) && !empty($account_info['iwp_gdrive'])) {
86
+
87
+ $this->update_status($task_name,'gDrive');
88
+ $account_info['iwp_gdrive']['backup_file'] = $backup_file;
89
+ iwp_mmb_print_flush('google Drive upload: Start');
90
+ $gdrive_result = $this->google_drive_backup($account_info['iwp_gdrive']);
91
+ $this->update_status($task_name, 'gDrive', true);
92
+ iwp_mmb_print_flush('google Drive upload: End');
93
+
94
+ if ($gdrive_result == false && $del_host_file) {
95
+ @unlink($backup_file);
96
+ $return = false;
97
+ }
98
+
99
+ if (is_array($gdrive_result) && isset($gdrive_result['error'])) {
100
+ return $gdrive_result;
101
+ }
102
+
103
+ //update the tasks different method for gDrive
104
+
105
+ if(!empty($gdrive_result))
106
+ {
107
+ $tasks = $this->tasks;
108
+ $task = $tasks['Backup Now'];
109
+ $results = $task['task_results'];
110
+ if (is_array($results) && count($results)) {
111
+ $results[count($results) - 1]['gDrive'] = $gdrive_result;
112
+ //$results[count($results) - 1]['gDriveOrgFileName'] = basename($backup_url); //not required
113
+ unset($results[count($results) - 1]['server']);
114
+ }
115
+
116
+ /* $paths['gDrive'] = $gdrive_result; //different from other upload ; storing the gDrive backupfile ID in the paths array for delete operation
117
+ $paths['gDriveOrgFileName'] = basename($backup_url); */
118
+
119
+ $tasks['Backup Now']['task_results'] = $results;
120
+ $this->tasks = $tasks;
121
+
122
+ $this->update_status($task_name,'gDrive', true);
123
+ unset($paths['server']);
124
+ $return = true;
125
+ }
126
+ }
127
128
if ($return == true && $del_host_file) {
129
@unlink($backup_file);
addons/comments/comments.class.php CHANGED
@@ -34,7 +34,7 @@ class IWP_MMB_Comment extends IWP_MMB_Core
34
$status_sql = 'spam';
35
elseif ( 'trash' == $status )
36
$status_sql = 'trash';
37
- $sql = "update ".$wpdb->prefix."comments set comment_approved = '%s' where comment_ID = '%s'";
38
$success = $wpdb->query($wpdb->prepare($sql, $status_sql, $comment_id));
39
40
34
$status_sql = 'spam';
35
elseif ( 'trash' == $status )
36
$status_sql = 'trash';
37
+ $sql = "update ".$wpdb->base_prefix."comments set comment_approved = '%s' where comment_ID = '%s'";
38
$success = $wpdb->query($wpdb->prepare($sql, $status_sql, $comment_id));
39
40
addons/manage_users/user.class.php CHANGED
@@ -42,7 +42,7 @@ class IWP_MMB_User extends IWP_MMB_Core
42
$users = array();
43
$userlevel_qry = "('".implode("','",$userlevels)."')";
44
$userlevel_fallback_qry = "('%".implode("%','%",$level_strings)."%')";
45
- $field = $wpdb->prefix."capabilities";
46
47
$user_metas = $wpdb->get_results("SELECT * from $wpdb->usermeta WHERE meta_key = '$field' AND meta_value IN $userlevel_fallback_qry");
48
if($user_metas == false || empty($user_metas)){
@@ -195,7 +195,7 @@ class IWP_MMB_User extends IWP_MMB_Core
195
//Check if user is the only one admin on the site
196
function last_admin($user_obj){
197
global $wpdb;
198
- $field = $wpdb->prefix."capabilities";
199
$capabilities = array_map('strtolower',array_keys($user_obj->$field));
200
$result = count_users();
201
if(in_array('administrator',$capabilities)){
42
$users = array();
43
$userlevel_qry = "('".implode("','",$userlevels)."')";
44
$userlevel_fallback_qry = "('%".implode("%','%",$level_strings)."%')";
45
+ $field = $wpdb->base_prefix."capabilities";
46
47
$user_metas = $wpdb->get_results("SELECT * from $wpdb->usermeta WHERE meta_key = '$field' AND meta_value IN $userlevel_fallback_qry");
48
if($user_metas == false || empty($user_metas)){
195
//Check if user is the only one admin on the site
196
function last_admin($user_obj){
197
global $wpdb;
198
+ $field = $wpdb->base_prefix."capabilities";
199
$capabilities = array_map('strtolower',array_keys($user_obj->$field));
200
$result = count_users();
201
if(in_array('administrator',$capabilities)){
addons/post_links/post.class.php CHANGED
@@ -440,7 +440,7 @@ class IWP_MMB_Post extends IWP_MMB_Core
440
$success = false;
441
442
if(in_array($status, array('draft', 'publish', 'trash'))){
443
- $sql = "update ".$wpdb->prefix."posts set post_status = '$status' where ID = '$post_id'";
444
$success = $wpdb->query($sql);
445
}
446
440
$success = false;
441
442
if(in_array($status, array('draft', 'publish', 'trash'))){
443
+ $sql = "update ".$wpdb->base_prefix."posts set post_status = '$status' where ID = '$post_id'";
444
$success = $wpdb->query($sql);
445
}
446
backup.class.php CHANGED
@@ -355,7 +355,7 @@ function delete_task_now($task_name){
355
$hash = md5(time());
356
$label = $type ? $type : 'manual';
357
$backup_file = $new_file_path . '/' . $this->site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
358
- $backup_url = WP_CONTENT_URL . '/infinitewp/backups/' . $this->site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
359
360
//Optimize tables?
361
if (isset($optimize_tables) && !empty($optimize_tables)) {
@@ -474,6 +474,11 @@ function delete_task_now($task_name){
474
if (isset($backup_settings[$task_name]['task_args']['account_info']['iwp_dropbox'])) {
475
$paths['dropbox'] = basename($backup_url);
476
}
477
478
if (isset($backup_settings[$task_name]['task_args']['account_info']['iwp_email'])) {
479
$paths['email'] = basename($backup_url);
@@ -552,7 +557,28 @@ function delete_task_now($task_name){
552
$this->wpdb_reconnect();
553
$this->update_status($task_name, 'dropbox', true);
554
}
555
-
556
if ($del_host_file) {
557
@unlink($backup_file);
558
}
@@ -1021,7 +1047,9 @@ function delete_task_now($task_name){
1021
global $wpdb;
1022
$paths = $this->check_mysql_paths();
1023
$brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
1024
- $command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" > ' . $brace . $file . $brace;
1025
iwp_mmb_print_flush('DB DUMP CMD: Start');
1026
ob_start();
1027
$result = $this->iwp_mmb_exec($command);
@@ -1054,7 +1082,7 @@ function delete_task_now($task_name){
1054
}
1055
$_count = 0;
1056
$insert_sql = '';
1057
- $result = mysql_query( 'SHOW TABLES' );
1058
if(!$result)
1059
{
1060
return array(
@@ -1133,7 +1161,7 @@ function delete_task_now($task_name){
1133
else{
1134
iwp_mmb_print_flush('DB DUMP PHP Fail-safe: Start');
1135
file_put_contents($file, '');//safe to reset any old data
1136
- $tables = $wpdb->get_results('SHOW TABLES', ARRAY_N);
1137
foreach ($tables as $table) {
1138
1139
//drop existing table
@@ -1365,6 +1393,25 @@ function iwp_mmb_direct_to_any_copy($source, $destination, $overwrite = false, $
1365
);
1366
}
1367
}
1368
1369
1370
$what = $tasks[$task_name]['task_args']['what'];
@@ -1417,7 +1464,6 @@ function iwp_mmb_direct_to_any_copy($source, $destination, $overwrite = false, $
1417
);
1418
}
1419
1420
- //echo '<pre>$new_temp_folder:'; var_dump($new_temp_folder); echo '</pre>';
1421
1422
1423
$remote_abspath = $wp_filesystem->abspath();
@@ -2242,6 +2288,219 @@ function ftp_backup($args)
2242
}
2243
}
2244
2245
2246
function remove_amazons3_backup($args)
2247
{
@@ -2281,6 +2540,121 @@ function ftp_backup($args)
2281
}
2282
//IWP Remove ends here
2283
2284
2285
function schedule_next($type, $schedule)
2286
{
@@ -2433,7 +2807,7 @@ function get_next_schedules()
2433
@unlink($backups[$task_name]['task_results'][$i]['server']['file_path']);
2434
}
2435
2436
- if (isset($backups[$task_name]['task_results'][$i]['ftp'])) {
2437
$ftp_file = $backups[$task_name]['task_results'][$i]['ftp'];
2438
$args = $backups[$task_name]['task_args']['account_info']['iwp_ftp'];
2439
$args['backup_file'] = $ftp_file;
@@ -2454,6 +2828,13 @@ function get_next_schedules()
2454
$args['backup_file'] = $dropbox_file;
2455
$this->remove_dropbox_backup($args);
2456
}
2457
//Remove database backup info
2458
unset($backups[$task_name]['task_results'][$i]);
2459
@@ -2515,6 +2896,12 @@ function get_next_schedules()
2515
$this->remove_dropbox_backup($args);
2516
}
2517
2518
2519
unset($backups[$result_id]);
2520
355
$hash = md5(time());
356
$label = $type ? $type : 'manual';
357
$backup_file = $new_file_path . '/' . $this->site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
358
+ $backup_url = content_url() . '/infinitewp/backups/' . $this->site_name . '_' . $label . '_' . $what . '_' . date('Y-m-d') . '_' . $hash . '.zip';
359
360
//Optimize tables?
361
if (isset($optimize_tables) && !empty($optimize_tables)) {
474
if (isset($backup_settings[$task_name]['task_args']['account_info']['iwp_dropbox'])) {
475
$paths['dropbox'] = basename($backup_url);
476
}
477
+
478
+ if (isset($backup_settings[$task_name]['task_args']['account_info']['iwp_gdrive'])) {
479
+ //$paths['gDrive'] = basename($backup_url);
480
+ $paths['gDriveOrgFileName'] = basename($backup_url);
481
+ }
482
483
if (isset($backup_settings[$task_name]['task_args']['account_info']['iwp_email'])) {
484
$paths['email'] = basename($backup_url);
557
$this->wpdb_reconnect();
558
$this->update_status($task_name, 'dropbox', true);
559
}
560
+ if (isset($account_info['iwp_gdrive']) && !empty($account_info['iwp_gdrive'])) {
561
+
562
+ $this->update_status($task_name,'gDrive');
563
+ $account_info['iwp_gdrive']['backup_file'] = $backup_file;
564
+ iwp_mmb_print_flush('google Drive upload: Start');
565
+ $gdrive_result = $this->google_drive_backup($account_info['iwp_gdrive']);
566
+ iwp_mmb_print_flush('google Drive upload: End');
567
+
568
+ if ($gdrive_result == false && $del_host_file) {
569
+ @unlink($backup_file);
570
+ }
571
+
572
+ if (is_array($gdrive_result) && isset($gdrive_result['error'])) {
573
+ return $gdrive_result;
574
+ }
575
+
576
+ $paths['gDrive'] = $gdrive_result; //different from other upload ; storing the gDrive backupfile ID in the paths array for delete operation
577
+ $paths['gDriveOrgFileName'] = basename($backup_url);
578
+
579
+ $this->update_status($task_name,'gDrive', true);
580
+ unset($paths['server']);
581
+ }
582
if ($del_host_file) {
583
@unlink($backup_file);
584
}
1047
global $wpdb;
1048
$paths = $this->check_mysql_paths();
1049
$brace = (substr(PHP_OS, 0, 3) == 'WIN') ? '"' : '';
1050
+ $command0 = $wpdb->get_col('SHOW TABLES LIKE "'.$wpdb->base_prefix.'%"');
1051
+ $wp_tables = join("\" \"",$command0);
1052
+ $command = $brace . $paths['mysqldump'] . $brace . ' --force --host="' . DB_HOST . '" --user="' . DB_USER . '" --password="' . DB_PASSWORD . '" --add-drop-table --skip-lock-tables "' . DB_NAME . '" "'.$wp_tables.'" > ' . $brace . $file . $brace;
1053
iwp_mmb_print_flush('DB DUMP CMD: Start');
1054
ob_start();
1055
$result = $this->iwp_mmb_exec($command);
1082
}
1083
$_count = 0;
1084
$insert_sql = '';
1085
+ $result = mysql_query( 'SHOW TABLES LIKE "'.$wpdb->base_prefix.'%"' );
1086
if(!$result)
1087
{
1088
return array(
1161
else{
1162
iwp_mmb_print_flush('DB DUMP PHP Fail-safe: Start');
1163
file_put_contents($file, '');//safe to reset any old data
1164
+ $tables = $wpdb->get_results('SHOW TABLES LIKE "'.$wpdb->base_prefix.'%"', ARRAY_N);
1165
foreach ($tables as $table) {
1166
1167
//drop existing table
1393
);
1394
}
1395
}
1396
+ elseif(isset($task['task_results'][$result_id]['gDrive'])){
1397
+ $gdrive_file = $task['task_results'][$result_id]['gDrive'];
1398
+ $args = $task['task_args']['account_info']['iwp_gdrive'];
1399
+ $args['backup_file'] = $gdrive_file;
1400
+ iwp_mmb_print_flush('gDrive download: Start');
1401
+ $backup_file = $this->get_google_drive_backup($args);
1402
+ iwp_mmb_print_flush('gDrive download: End');
1403
+
1404
+ if(is_array($backup_file) && array_key_exists('error', $backup_file))
1405
+ {
1406
+ return $backup_file;
1407
+ }
1408
+
1409
+ if ($backup_file == false) {
1410
+ return array(
1411
+ 'error' => 'Failed to download file from gDrive.'
1412
+ );
1413
+ }
1414
+ }
1415
1416
1417
$what = $tasks[$task_name]['task_args']['what'];
1464
);
1465
}
1466
1467
1468
1469
$remote_abspath = $wp_filesystem->abspath();
2288
}
2289
}
2290
2291
+ function google_drive_backup($args = '', $uploadid = null, $offset = 0)
2292
+ {
2293
+
2294
+ require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/Google/Client.php');
2295
+ require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/Google/Http/MediaFileUpload.php');
2296
+ require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/Google/Service/Drive.php');
2297
+
2298
+ //$this -> hisID = $historyID;
2299
+
2300
+ $upload_file_block_size = 1 *1024 *1024;
2301
+ $iwp_folder_id = '';
2302
+ $sub_folder_id = '';
2303
+ $create_sub_folder = $args['gdrive_site_folder'];
2304
+ $sub_folder_name = $this->site_name;
2305
+ //$task_result = $this->getRequiredData($historyID, "taskResults");
2306
+
2307
+ $fileSizeUploaded = 0;
2308
+ $resumeURI = false;
2309
+
2310
+ $client = new Google_Client();
2311
+ $client->setClientId($args['clientID']);
2312
+ $client->setClientSecret($args['clientSecretKey']);
2313
+ $client->setRedirectUri($args['redirectURL']);
2314
+ $client->setScopes(array(
2315
+ 'https://www.googleapis.com/auth/drive',
2316
+ 'https://www.googleapis.com/auth/userinfo.email',
2317
+ 'https://www.googleapis.com/auth/userinfo.profile'));
2318
+
2319
+
2320
+ $accessToken = $args['token'];
2321
+ $refreshToken = $accessToken['refresh_token'];
2322
+ $backup_file = $args['backup_file'];
2323
+
2324
+ try
2325
+ {
2326
+ $client->refreshToken($refreshToken);
2327
+ }
2328
+ catch(Exception $e)
2329
+ {
2330
+ echo 'google Error ', $e->getMessage(), "\n";
2331
+ return array("error" => $e->getMessage());
2332
+ }
2333
+
2334
+ $service = new Google_Service_Drive($client);
2335
+
2336
+ //create folder if not present
2337
+ try
2338
+ {
2339
+ $parameters = array();
2340
+ $parameters['q'] = "title = 'infinitewp' and trashed = false and mimeType= 'application/vnd.google-apps.folder'";
2341
+ $files = $service->files->listFiles($parameters);
2342
+ $list_result = array();
2343
+ $list_result = array_merge($list_result, $files->getItems());
2344
+ $list_result = (array)$list_result;
2345
+
2346
+ if(empty($list_result))
2347
+ {
2348
+ $file = new Google_Service_Drive_DriveFile();
2349
+ $file->setTitle('infinitewp');
2350
+ $file->setMimeType('application/vnd.google-apps.folder');
2351
+
2352
+ $createdFolder = $service->files->insert($file, array(
2353
+ 'mimeType' => 'application/vnd.google-apps.folder',
2354
+ ));
2355
+ if($createdFolder)
2356
+ {
2357
+ $createdFolder = (array)$createdFolder;
2358
+ $iwp_folder_id = $createdFolder['id'];
2359
+ }
2360
+ }
2361
+ else
2362
+ {
2363
+ $list_result = (array)$list_result[0];
2364
+ $iwp_folder_id = $list_result['id'];
2365
+ }
2366
+ }catch (Exception $e){
2367
+ print "An error occurred: " . $e->getMessage();
2368
+ return array('error' => $e->getMessage());
2369
+ }
2370
+
2371
+ //create sub folder by site name
2372
+ if($create_sub_folder)
2373
+ {
2374
+ $parameters = array();
2375
+ $parameters['q'] = "title = '$sub_folder_name' and trashed = false and mimeType = 'application/vnd.google-apps.folder'";
2376
+ $files = $service->files->listFiles($parameters);
2377
+ $list_result = array();
2378
+ $list_result = array_merge($list_result, $files->getItems());
2379
+ $list_result = (array)$list_result;
2380
+
2381
+ if(empty($list_result))
2382
+ {
2383
+ $file = new Google_Service_Drive_DriveFile();
2384
+ $file->setTitle($sub_folder_name);
2385
+ $file->setMimeType('application/vnd.google-apps.folder');
2386
+
2387
+ //setting parent as infinitewpFolder
2388
+ $parent = new Google_Service_Drive_ParentReference();
2389
+ $parent->setId($iwp_folder_id);
2390
+ $file->setParents(array($parent));
2391
+
2392
+ $createdFolder = $service->files->insert($file, array(
2393
+ 'mimeType' => 'application/vnd.google-apps.folder',
2394
+ ));
2395
+ if($createdFolder)
2396
+ {
2397
+ $createdFolder = (array)$createdFolder;
2398
+ $sub_folder_id = $createdFolder['id'];
2399
+ }
2400
+ }
2401
+ else
2402
+ {
2403
+ $list_result = (array)$list_result[0];
2404
+ $sub_folder_id = $list_result['id'];
2405
+ }
2406
+ }
2407
+
2408
+
2409
+ //Insert a file
2410
+ $file = new Google_Service_Drive_DriveFile();
2411
+ $file->setTitle(basename($backup_file));
2412
+ $file->setMimeType('binary/octet-stream');
2413
+
2414
+ // Set the Parent Folder on Google Drive
2415
+ $parent = new Google_Service_Drive_ParentReference();
2416
+ if(empty($sub_folder_id))
2417
+ {
2418
+ $parent->setId($iwp_folder_id);
2419
+ }
2420
+ else
2421
+ {
2422
+ $parent->setId($sub_folder_id);
2423
+ }
2424
+ $file->setParents(array($parent));
2425
+
2426
+ $gDriveID = '';
2427
+ try
2428
+ {
2429
+ if(false)
2430
+ {
2431
+ //single upload
2432
+ $data = file_get_contents($backup_file);
2433
+ $createdFile = (array)$service->files->insert($file, array(
2434
+ 'data' => $data,
2435
+ //'mimeType' => 'text/plain',
2436
+ ));
2437
+ $gDriveID = $createdFile['id'];
2438
+ }
2439
+
2440
+ //multipart upload
2441
+
2442
+ if(true)
2443
+ {
2444
+ // Call the API with the media upload, defer so it doesn't immediately return.
2445
+ $client->setDefer(true);
2446
+ $request = $service->files->insert($file);
2447
+
2448
+ // Create a media file upload to represent our upload process.
2449
+ $media = new Google_Http_MediaFileUpload($client, $request, 'application/zip', null, true, $upload_file_block_size);
2450
+ $media->setFileSize(filesize($backup_file));
2451
+
2452
+ $status = false;
2453
+ $handle = fopen($backup_file, "rb");
2454
+ fseek($handle, $fileSizeUploaded);
2455
+
2456
+ /* $resArray = array (
2457
+ 'status' => 'completed',
2458
+ 'backupParentHID' => $historyID,
2459
+ ); */
2460
+
2461
+ while (!$status && !feof($handle))
2462
+ {
2463
+ $chunk = fread($handle, $upload_file_block_size);
2464
+ $statusArray = $media->nextChunk($chunk, $resumeURI, $fileSizeUploaded);
2465
+ $status = $statusArray['status'];
2466
+ $resumeURI = $statusArray['resumeURI'];
2467
+ //$fileSizeUploaded = ftell($handle);
2468
+ $fileSizeUploaded = $statusArray['progress'];
2469
+ }
2470
+
2471
+ $result = false;
2472
+ if($status != false) {
2473
+ $result = $status;
2474
+ }
2475
+
2476
+ fclose($handle);
2477
+ $client->setDefer(false);
2478
+
2479
+ $completeBackupResult = (array)$status;
2480
+
2481
+ //$gDriveID = $createdFile['id'];
2482
+ $gDriveID = $completeBackupResult['id'];
2483
+ }
2484
+ }
2485
+ catch (Exception $e)
2486
+ {
2487
+ echo "An error occurred: " . $e->getMessage();
2488
+ return array("error" => $e->getMessage());
2489
+ }
2490
+
2491
+ /* if($del_host_file)
2492
+ {
2493
+ unset($task_result['task_results'][$historyID]['server']);
2494
+ @unlink($backup_file);
2495
+ } */
2496
+
2497
+ //$test_this_task = $this->get_this_tasks();
2498
+
2499
+ //$tasksThere = unserialize($test_this_task['taskResults']);
2500
+
2501
+ return $gDriveID;
2502
+ }
2503
+
2504
2505
function remove_amazons3_backup($args)
2506
{
2540
}
2541
//IWP Remove ends here
2542
2543
+ function get_google_drive_backup($args)
2544
+ {
2545
+ require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/Google/Client.php');
2546
+ require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/Google/Service/Drive.php');
2547
+
2548
+ //refresh token
2549
+ $client = new Google_Client();
2550
+ $client->setClientId($args['clientID']);
2551
+ $client->setClientSecret($args['clientSecretKey']);
2552
+ $client->setRedirectUri($args['redirectURL']);
2553
+ $client->setScopes(array(
2554
+ 'https://www.googleapis.com/auth/drive',
2555
+ 'https://www.googleapis.com/auth/userinfo.email',
2556
+ 'https://www.googleapis.com/auth/userinfo.profile'));
2557
+
2558
+ //$client->setUseObjects(true);
2559
+
2560
+ $accessToken = $args['token'];
2561
+ $refreshToken = $accessToken['refresh_token'];
2562
+
2563
+ try
2564
+ {
2565
+ $client->refreshToken($refreshToken);
2566
+ }
2567
+ catch(Exception $e)
2568
+ {
2569
+ echo 'google Error ', $e->getMessage(), "\n";
2570
+ return array("error" => $e->getMessage());
2571
+ }
2572
+
2573
+ //downloading the file
2574
+ $service = new Google_Service_Drive($client);
2575
+
2576
+ $file = $service->files->get($args['backup_file']);
2577
+
2578
+ $downloadUrl = $file->getDownloadUrl();
2579
+
2580
+ $temp = wp_tempnam('iwp_temp_backup.zip');
2581
+
2582
+ try
2583
+ {
2584
+ if ($downloadUrl)
2585
+ {
2586
+ $request = new Google_Http_Request($downloadUrl, 'GET', null, null);
2587
+
2588
+ $signHttpRequest = $client->getAuth()->sign($request);
2589
+ $httpRequest = $client->getIo()->makeRequest($signHttpRequest);
2590
+
2591
+ if ($httpRequest->getResponseHttpCode() == 200) {
2592
+ file_put_contents($temp, $httpRequest->getResponseBody());
2593
+ return $temp;
2594
+ } else {
2595
+ // An error occurred.
2596
+ return array("error" => "There is some error.");
2597
+ }
2598
+ }
2599
+ else
2600
+ {
2601
+ // The file doesn't have any content stored on Drive.
2602
+ return array("error" => "Google Drive file doesnt have nay content.");
2603
+ }
2604
+ }catch(Exception $e)
2605
+ {
2606
+ echo 'google Error ', $e->getMessage(), "\n";
2607
+ return array("error" => $e->getMessage());
2608
+ }
2609
+
2610
+
2611
+ }
2612
+
2613
+ function remove_google_drive_backup($args)
2614
+ {
2615
+ /* require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/google-api/Google_Client.php');
2616
+ require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/google-api/contrib/Google_DriveService.php'); */
2617
+ require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/Google/Client.php');
2618
+ require_once($GLOBALS['iwp_mmb_plugin_dir'].'/lib/Google/Service/Drive.php');
2619
+
2620
+ $client = new Google_Client();
2621
+ $client->setClientId($args['clientID']);
2622
+ $client->setClientSecret($args['clientSecretKey']);
2623
+ $client->setRedirectUri($args['redirectURL']);
2624
+ $client->setScopes(array(
2625
+ 'https://www.googleapis.com/auth/drive',
2626
+ 'https://www.googleapis.com/auth/userinfo.email',
2627
+ 'https://www.googleapis.com/auth/userinfo.profile'));
2628
+
2629
+ //$client->setUseObjects(true);
2630
+
2631
+ $accessToken = $args['token'];
2632
+ $refreshToken = $accessToken['refresh_token'];
2633
+
2634
+ try
2635
+ {
2636
+ $client->refreshToken($refreshToken);
2637
+ }
2638
+ catch(Exception $e)
2639
+ {
2640
+ echo 'google Error ', $e->getMessage(), "\n";
2641
+ return array("error" => $e->getMessage());
2642
+ }
2643
+
2644
+ $service = new Google_Service_Drive($client);
2645
+
2646
+ try
2647
+ {
2648
+ echo "\n".'backup_file:'.$args['backup_file'];
2649
+ $service->files->delete($args['backup_file']);
2650
+ }
2651
+ catch (Exception $e)
2652
+ {
2653
+ echo "\nAn error occurred: " . $e->getMessage();
2654
+ return array("error" => $e->getMessage());
2655
+ }
2656
+
2657
+ }
2658
2659
function schedule_next($type, $schedule)
2660
{
2807
@unlink($backups[$task_name]['task_results'][$i]['server']['file_path']);
2808
}
2809
2810
+ if (isset($backups[$task_name]['task_results'][$i]['ftp'])) {
2811
$ftp_file = $backups[$task_name]['task_results'][$i]['ftp'];
2812
$args = $backups[$task_name]['task_args']['account_info']['iwp_ftp'];
2813
$args['backup_file'] = $ftp_file;
2828
$args['backup_file'] = $dropbox_file;
2829
$this->remove_dropbox_backup($args);
2830
}
2831
+
2832
+ if (isset($backups[$task_name]['task_results'][$i]['gDrive'])) {
2833
+ $gdrive_file = $backups[$task_name]['task_results'][$i]['gDrive'];
2834
+ $args = $backups[$task_name]['task_args']['account_info']['iwp_gdrive'];
2835
+ $args['backup_file'] = $gdrive_file;
2836
+ $this->remove_google_drive_backup($args);
2837
+ }
2838
//Remove database backup info
2839
unset($backups[$task_name]['task_results'][$i]);
2840
2896
$this->remove_dropbox_backup($args);
2897
}
2898
2899
+ if (isset($backup['gDrive'])) {
2900
+ $g_drive_file = $backup['gDrive'];
2901
+ $args = $tasks[$task_name]['task_args']['account_info']['iwp_gdrive'];
2902
+ $args['backup_file'] = $g_drive_file;
2903
+ $this->remove_google_drive_backup($args);
2904
+ }
2905
2906
unset($backups[$result_id]);
2907
helper.class.php CHANGED
@@ -432,7 +432,7 @@ class IWP_MMB_Helper
432
}
433
434
$user = (array) $this->iwp_mmb_get_user_info( $username );
435
- if ((isset($user[$wpdb->prefix . 'user_level']) && $user[$wpdb->prefix . 'user_level'] == 10) || isset($user[$wpdb->prefix . 'capabilities']['administrator']) ||
436
(isset($user['caps']['administrator']) && $user['caps']['administrator'] == 1)){
437
return true;
438
}
432
}
433
434
$user = (array) $this->iwp_mmb_get_user_info( $username );
435
+ if ((isset($user[$wpdb->base_prefix . 'user_level']) && $user[$wpdb->base_prefix . 'user_level'] == 10) || isset($user[$wpdb->base_prefix . 'capabilities']['administrator']) ||
436
(isset($user['caps']['administrator']) && $user['caps']['administrator'] == 1)){
437
return true;
438
}
init.php CHANGED
@@ -4,7 +4,7 @@ Plugin Name: InfiniteWP - Client
4
Plugin URI: http://infinitewp.com/
5
Description: This is the client plugin of InfiniteWP that communicates with the InfiniteWP Admin panel.
6
Author: Revmakx
7
- Version: 1.2.11
8
Author URI: http://www.revmakx.com
9
*/
10
/************************************************************
@@ -26,7 +26,7 @@ Author URI: http://www.revmakx.com
26
**************************************************************/
27
28
if(!defined('IWP_MMB_CLIENT_VERSION'))
29
- define('IWP_MMB_CLIENT_VERSION', '1.2.11');
30
31
32
if ( !defined('IWP_MMB_XFRAME_COOKIE')){
4
Plugin URI: http://infinitewp.com/
5
Description: This is the client plugin of InfiniteWP that communicates with the InfiniteWP Admin panel.
6
Author: Revmakx
7
+ Version: 1.2.12
8
Author URI: http://www.revmakx.com
9
*/
10
/************************************************************
26
**************************************************************/
27
28
if(!defined('IWP_MMB_CLIENT_VERSION'))
29
+ define('IWP_MMB_CLIENT_VERSION', '1.2.12');
30
31
32
if ( !defined('IWP_MMB_XFRAME_COOKIE')){
lib/Google/Auth/Abstract.php ADDED
@@ -0,0 +1,41 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Http/Request.php";
18
+
19
+ /**
20
+ * Abstract class for the Authentication in the API client
21
+ * @author Chris Chabot <chabotc@google.com>
22
+ *
23
+ */
24
+ abstract class Google_Auth_Abstract
25
+ {
26
+ /**
27
+ * An utility function that first calls $this->auth->sign($request) and then
28
+ * executes makeRequest() on that signed request. Used for when a request
29
+ * should be authenticated
30
+ * @param Google_Http_Request $request
31
+ * @return Google_Http_Request $request
32
+ */
33
+ abstract public function authenticatedRequest(Google_Http_Request $request);
34
+
35
+ abstract public function authenticate($code);
36
+ abstract public function sign(Google_Http_Request $request);
37
+ abstract public function createAuthUrl($scope);
38
+
39
+ abstract public function refreshToken($refreshToken);
40
+ abstract public function revokeToken();
41
+ }
lib/Google/Auth/AssertionCredentials.php ADDED
@@ -0,0 +1,133 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2012 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Auth/OAuth2.php";
19
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Signer/P12.php";
20
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Utils.php";
21
+
22
+ /**
23
+ * Credentials object used for OAuth 2.0 Signed JWT assertion grants.
24
+ *
25
+ * @author Chirag Shah <chirags@google.com>
26
+ */
27
+ class Google_Auth_AssertionCredentials
28
+ {
29
+ const MAX_TOKEN_LIFETIME_SECS = 3600;
30
+
31
+ public $serviceAccountName;
32
+ public $scopes;
33
+ public $privateKey;
34
+ public $privateKeyPassword;
35
+ public $assertionType;
36
+ public $sub;
37
+ /**
38
+ * @deprecated
39
+ * @link http://tools.ietf.org/html/draft-ietf-oauth-json-web-token-06
40
+ */
41
+ public $prn;
42
+ private $useCache;
43
+
44
+ /**
45
+ * @param $serviceAccountName
46
+ * @param $scopes array List of scopes
47
+ * @param $privateKey
48
+ * @param string $privateKeyPassword
49
+ * @param string $assertionType
50
+ * @param bool|string $sub The email address of the user for which the
51
+ * application is requesting delegated access.
52
+ * @param bool useCache Whether to generate a cache key and allow
53
+ * automatic caching of the generated token.
54
+ */
55
+ public function __construct(
56
+ $serviceAccountName,
57
+ $scopes,
58
+ $privateKey,
59
+ $privateKeyPassword = 'notasecret',
60
+ $assertionType = 'http://oauth.net/grant_type/jwt/1.0/bearer',
61
+ $sub = false,
62
+ $useCache = true
63
+ ) {
64
+ $this->serviceAccountName = $serviceAccountName;
65
+ $this->scopes = is_string($scopes) ? $scopes : implode(' ', $scopes);
66
+ $this->privateKey = $privateKey;
67
+ $this->privateKeyPassword = $privateKeyPassword;
68
+ $this->assertionType = $assertionType;
69
+ $this->sub = $sub;
70
+ $this->prn = $sub;
71
+ $this->useCache = $useCache;
72
+ }
73
+
74
+ /**
75
+ * Generate a unique key to represent this credential.
76
+ * @return string
77
+ */
78
+ public function getCacheKey()
79
+ {
80
+ if (!$this->useCache) {
81
+ return false;
82
+ }
83
+ $h = $this->sub;
84
+ $h .= $this->assertionType;
85
+ $h .= $this->privateKey;
86
+ $h .= $this->scopes;
87
+ $h .= $this->serviceAccountName;
88
+ return md5($h);
89
+ }
90
+
91
+ public function generateAssertion()
92
+ {
93
+ $now = time();
94
+
95
+ $jwtParams = array(
96
+ 'aud' => Google_Auth_OAuth2::OAUTH2_TOKEN_URI,
97
+ 'scope' => $this->scopes,
98
+ 'iat' => $now,
99
+ 'exp' => $now + self::MAX_TOKEN_LIFETIME_SECS,
100
+ 'iss' => $this->serviceAccountName,
101
+ );
102
+
103
+ if ($this->sub !== false) {
104
+ $jwtParams['sub'] = $this->sub;
105
+ } else if ($this->prn !== false) {
106
+ $jwtParams['prn'] = $this->prn;
107
+ }
108
+
109
+ return $this->makeSignedJwt($jwtParams);
110
+ }
111
+
112
+ /**
113
+ * Creates a signed JWT.
114
+ * @param array $payload
115
+ * @return string The signed JWT.
116
+ */
117
+ private function makeSignedJwt($payload)
118
+ {
119
+ $header = array('typ' => 'JWT', 'alg' => 'RS256');
120
+
121
+ $segments = array(
122
+ Google_Utils::urlSafeB64Encode(json_encode($header)),
123
+ Google_Utils::urlSafeB64Encode(json_encode($payload))
124
+ );
125
+
126
+ $signingInput = implode('.', $segments);
127
+ $signer = new Google_Signer_P12($this->privateKey, $this->privateKeyPassword);
128
+ $signature = $signer->sign($signingInput);
129
+ $segments[] = Google_Utils::urlSafeB64Encode($signature);
130
+
131
+ return implode(".", $segments);
132
+ }
133
+ }
lib/Google/Auth/Exception.php ADDED
@@ -0,0 +1,22 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Exception.php";
19
+
20
+ class Google_Auth_Exception extends Google_Exception
21
+ {
22
+ }
lib/Google/Auth/LoginTicket.php ADDED
@@ -0,0 +1,69 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2011 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Auth/Exception.php";
19
+
20
+ /**
21
+ * Class to hold information about an authenticated login.
22
+ *
23
+ * @author Brian Eaton <beaton@google.com>
24
+ */
25
+ class Google_Auth_LoginTicket
26
+ {
27
+ const USER_ATTR = "sub";
28
+
29
+ // Information from id token envelope.
30
+ private $envelope;
31
+
32
+ // Information from id token payload.
33
+ private $payload;
34
+
35
+ /**
36
+ * Creates a user based on the supplied token.
37
+ *
38
+ * @param string $envelope Header from a verified authentication token.
39
+ * @param string $payload Information from a verified authentication token.
40
+ */
41
+ public function __construct($envelope, $payload)
42
+ {
43
+ $this->envelope = $envelope;
44
+ $this->payload = $payload;
45
+ }
46
+
47
+ /**
48
+ * Returns the numeric identifier for the user.
49
+ * @throws Google_Auth_Exception
50
+ * @return
51
+ */
52
+ public function getUserId()
53
+ {
54
+ if (array_key_exists(self::USER_ATTR, $this->payload)) {
55
+ return $this->payload[self::USER_ATTR];
56
+ }
57
+ throw new Google_Auth_Exception("No user_id in token");
58
+ }
59
+
60
+ /**
61
+ * Returns attributes from the login ticket. This can contain
62
+ * various information about the user session.
63
+ * @return array
64
+ */
65
+ public function getAttributes()
66
+ {
67
+ return array("envelope" => $this->envelope, "payload" => $this->payload);
68
+ }
69
+ }
lib/Google/Auth/OAuth2.php ADDED
@@ -0,0 +1,587 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Auth/Abstract.php";
19
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Auth/AssertionCredentials.php";
20
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Auth/Exception.php";
21
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Auth/LoginTicket.php";
22
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Client.php";
23
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Http/Request.php";
24
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Utils.php";
25
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Verifier/Pem.php";
26
+
27
+ /**
28
+ * Authentication class that deals with the OAuth 2 web-server authentication flow
29
+ *
30
+ * @author Chris Chabot <chabotc@google.com>
31
+ * @author Chirag Shah <chirags@google.com>
32
+ *
33
+ */
34
+ class Google_Auth_OAuth2 extends Google_Auth_Abstract
35
+ {
36
+ const OAUTH2_REVOKE_URI = 'https://accounts.google.com/o/oauth2/revoke';
37
+ const OAUTH2_TOKEN_URI = 'https://accounts.google.com/o/oauth2/token';
38
+ const OAUTH2_AUTH_URL = 'https://accounts.google.com/o/oauth2/auth';
39
+ const CLOCK_SKEW_SECS = 300; // five minutes in seconds
40
+ const AUTH_TOKEN_LIFETIME_SECS = 300; // five minutes in seconds
41
+ const MAX_TOKEN_LIFETIME_SECS = 86400; // one day in seconds
42
+ const OAUTH2_ISSUER = 'accounts.google.com';
43
+
44
+ /** @var Google_Auth_AssertionCredentials $assertionCredentials */
45
+ private $assertionCredentials;
46
+
47
+ /**
48
+ * @var string The state parameters for CSRF and other forgery protection.
49
+ */
50
+ private $state;
51
+
52
+ /**
53
+ * @var array The token bundle.
54
+ */
55
+ private $token = array();
56
+
57
+ /**
58
+ * @var Google_Client the base client
59
+ */
60
+ private $client;
61
+
62
+ /**
63
+ * Instantiates the class, but does not initiate the login flow, leaving it
64
+ * to the discretion of the caller.
65
+ */
66
+ public function __construct(Google_Client $client)
67
+ {
68
+ $this->client = $client;
69
+ }
70
+
71
+ /**
72
+ * Perform an authenticated / signed apiHttpRequest.
73
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
74
+ * (which can modify the request in what ever way fits the auth mechanism)
75
+ * and then calls apiCurlIO::makeRequest on the signed request
76
+ *
77
+ * @param Google_Http_Request $request
78
+ * @return Google_Http_Request The resulting HTTP response including the
79
+ * responseHttpCode, responseHeaders and responseBody.
80
+ */
81
+ public function authenticatedRequest(Google_Http_Request $request)
82
+ {
83
+ $request = $this->sign($request);
84
+ return $this->client->getIo()->makeRequest($request);
85
+ }
86
+
87
+ /**
88
+ * @param string $code
89
+ * @throws Google_Auth_Exception
90
+ * @return string
91
+ */
92
+ public function authenticate($code)
93
+ {
94
+ if (strlen($code) == 0) {
95
+ throw new Google_Auth_Exception("Invalid code");
96
+ }
97
+
98
+ // We got here from the redirect from a successful authorization grant,
99
+ // fetch the access token
100
+ $request = new Google_Http_Request(
101
+ self::OAUTH2_TOKEN_URI,
102
+ 'POST',
103
+ array(),
104
+ array(
105
+ 'code' => $code,
106
+ 'grant_type' => 'authorization_code',
107
+ 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'),
108
+ 'client_id' => $this->client->getClassConfig($this, 'client_id'),
109
+ 'client_secret' => $this->client->getClassConfig($this, 'client_secret')
110
+ )
111
+ );
112
+ $request->disableGzip();
113
+ $response = $this->client->getIo()->makeRequest($request);
114
+
115
+ if ($response->getResponseHttpCode() == 200) {
116
+ $this->setAccessToken($response->getResponseBody());
117
+ $this->token['created'] = time();
118
+ return $this->getAccessToken();
119
+ } else {
120
+ $decodedResponse = json_decode($response->getResponseBody(), true);
121
+ if ($decodedResponse != null && $decodedResponse['error']) {
122
+ $decodedResponse = $decodedResponse['error'];
123
+ }
124
+ throw new Google_Auth_Exception(
125
+ sprintf(
126
+ "Error fetching OAuth2 access token, message: '%s'",
127
+ $decodedResponse
128
+ ),
129
+ $response->getResponseHttpCode()
130
+ );
131
+ }
132
+ }
133
+
134
+ /**
135
+ * Create a URL to obtain user authorization.
136
+ * The authorization endpoint allows the user to first
137
+ * authenticate, and then grant/deny the access request.
138
+ * @param string $scope The scope is expressed as a list of space-delimited strings.
139
+ * @return string
140
+ */
141
+ public function createAuthUrl($scope)
142
+ {
143
+ $params = array(
144
+ 'response_type' => 'code',
145
+ 'redirect_uri' => $this->client->getClassConfig($this, 'redirect_uri'),
146
+ 'client_id' => $this->client->getClassConfig($this, 'client_id'),
147
+ 'scope' => $scope,
148
+ 'access_type' => $this->client->getClassConfig($this, 'access_type'),
149
+ 'approval_prompt' => $this->client->getClassConfig($this, 'approval_prompt'),
150
+ );
151
+
152
+ // If the list of scopes contains plus.login, add request_visible_actions
153
+ // to auth URL.
154
+ $rva = $this->client->getClassConfig($this, 'request_visible_actions');
155
+ if (strpos($scope, 'plus.login') && strlen($rva) > 0) {
156
+ $params['request_visible_actions'] = $rva;
157
+ }
158
+
159
+ if (isset($this->state)) {
160
+ $params['state'] = $this->state;
161
+ }
162
+
163
+ return self::OAUTH2_AUTH_URL . "?" . http_build_query($params, '', '&');
164
+ }
165
+
166
+ /**
167
+ * @param string $token
168
+ * @throws Google_Auth_Exception
169
+ */
170
+ public function setAccessToken($token)
171
+ {
172
+ $token = json_decode($token, true);
173
+ if ($token == null) {
174
+ throw new Google_Auth_Exception('Could not json decode the token');
175
+ }
176
+ if (! isset($token['access_token'])) {
177
+ throw new Google_Auth_Exception("Invalid token format");
178
+ }
179
+ $this->token = $token;
180
+ }
181
+
182
+ public function getAccessToken()
183
+ {
184
+ return json_encode($this->token);
185
+ }
186
+
187
+ public function setState($state)
188
+ {
189
+ $this->state = $state;
190
+ }
191
+
192
+ public function setAssertionCredentials(Google_Auth_AssertionCredentials $creds)
193
+ {
194
+ $this->assertionCredentials = $creds;
195
+ }
196
+
197
+ /**
198
+ * Include an accessToken in a given apiHttpRequest.
199
+ * @param Google_Http_Request $request
200
+ * @return Google_Http_Request
201
+ * @throws Google_Auth_Exception
202
+ */
203
+ public function sign(Google_Http_Request $request)
204
+ {
205
+ // add the developer key to the request before signing it
206
+ if ($this->client->getClassConfig($this, 'developer_key')) {
207
+ $request->setQueryParam('key', $this->client->getClassConfig($this, 'developer_key'));
208
+ }
209
+
210
+ // Cannot sign the request without an OAuth access token.
211
+ if (null == $this->token && null == $this->assertionCredentials) {
212
+ return $request;
213
+ }
214
+
215
+ // Check if the token is set to expire in the next 30 seconds
216
+ // (or has already expired).
217
+ if ($this->isAccessTokenExpired()) {
218
+ if ($this->assertionCredentials) {
219
+ $this->refreshTokenWithAssertion();
220
+ } else {
221
+ if (! array_key_exists('refresh_token', $this->token)) {
222
+ throw new Google_Auth_Exception(
223
+ "The OAuth 2.0 access token has expired,"
224
+ ." and a refresh token is not available. Refresh tokens"
225
+ ." are not returned for responses that were auto-approved."
226
+ );
227
+ }
228
+ $this->refreshToken($this->token['refresh_token']);
229
+ }
230
+ }
231
+
232
+ // Add the OAuth2 header to the request
233
+ $request->setRequestHeaders(
234
+ array('Authorization' => 'Bearer ' . $this->token['access_token'])
235
+ );
236
+
237
+ return $request;
238
+ }
239
+
240
+ /**
241
+ * Fetches a fresh access token with the given refresh token.
242
+ * @param string $refreshToken
243
+ * @return void
244
+ */
245
+ public function refreshToken($refreshToken)
246
+ {
247
+ $this->refreshTokenRequest(
248
+ array(
249
+ 'client_id' => $this->client->getClassConfig($this, 'client_id'),
250
+ 'client_secret' => $this->client->getClassConfig($this, 'client_secret'),
251
+ 'refresh_token' => $refreshToken,
252
+ 'grant_type' => 'refresh_token'
253
+ )
254
+ );
255
+ }
256
+
257
+ /**
258
+ * Fetches a fresh access token with a given assertion token.
259
+ * @param Google_Auth_AssertionCredentials $assertionCredentials optional.
260
+ * @return void
261
+ */
262
+ public function refreshTokenWithAssertion($assertionCredentials = null)
263
+ {
264
+ if (!$assertionCredentials) {
265
+ $assertionCredentials = $this->assertionCredentials;
266
+ }
267
+
268
+ $cacheKey = $assertionCredentials->getCacheKey();
269
+
270
+ if ($cacheKey) {
271
+ // We can check whether we have a token available in the
272
+ // cache. If it is expired, we can retrieve a new one from
273
+ // the assertion.
274
+ $token = $this->client->getCache()->get($cacheKey);
275
+ if ($token) {
276
+ $this->setAccessToken($token);
277
+ }
278
+ if (!$this->isAccessTokenExpired()) {
279
+ return;
280
+ }
281
+ }
282
+
283
+ $this->refreshTokenRequest(
284
+ array(
285
+ 'grant_type' => 'assertion',
286
+ 'assertion_type' => $assertionCredentials->assertionType,
287
+ 'assertion' => $assertionCredentials->generateAssertion(),
288
+ )
289
+ );
290
+
291
+ if ($cacheKey) {
292
+ // Attempt to cache the token.
293
+ $this->client->getCache()->set(
294
+ $cacheKey,
295
+ $this->getAccessToken()
296
+ );
297
+ }
298
+ }
299
+
300
+ private function refreshTokenRequest($params)
301
+ {
302
+ $http = new Google_Http_Request(
303
+ self::OAUTH2_TOKEN_URI,
304
+ 'POST',
305
+ array(),
306
+ $params
307
+ );
308
+ $http->disableGzip();
309
+ $request = $this->client->getIo()->makeRequest($http);
310
+
311
+ $code = $request->getResponseHttpCode();
312
+ $body = $request->getResponseBody();
313
+ if (200 == $code) {
314
+ $token = json_decode($body, true);
315
+ if ($token == null) {
316
+ throw new Google_Auth_Exception("Could not json decode the access token");
317
+ }
318
+
319
+ if (! isset($token['access_token']) || ! isset($token['expires_in'])) {
320
+ throw new Google_Auth_Exception("Invalid token format");
321
+ }
322
+
323
+ $this->token['access_token'] = $token['access_token'];
324
+ $this->token['expires_in'] = $token['expires_in'];
325
+ $this->token['created'] = time();
326
+ } else {
327
+ throw new Google_Auth_Exception("Error refreshing the OAuth2 token, message: '$body'", $code);
328
+ }
329
+ }
330
+
331
+ /**
332
+ * Revoke an OAuth2 access token or refresh token. This method will revoke the current access
333
+ * token, if a token isn't provided.
334
+ * @throws Google_Auth_Exception
335
+ * @param string|null $token The token (access token or a refresh token) that should be revoked.
336
+ * @return boolean Returns True if the revocation was successful, otherwise False.
337
+ */
338
+ public function revokeToken($token = null)
339
+ {
340
+ if (!$token) {
341
+ if (!$this->token) {
342
+ // Not initialized, no token to actually revoke
343
+ return false;
344
+ } elseif (array_key_exists('refresh_token', $this->token)) {
345
+ $token = $this->token['refresh_token'];
346
+ } else {
347
+ $token = $this->token['access_token'];
348
+ }
349
+ }
350
+ $request = new Google_Http_Request(
351
+ self::OAUTH2_REVOKE_URI,
352
+ 'POST',
353
+ array(),
354
+ "token=$token"
355
+ );
356
+ $request->disableGzip();
357
+ $response = $this->client->getIo()->makeRequest($request);
358
+ $code = $response->getResponseHttpCode();
359
+ if ($code == 200) {
360
+ $this->token = null;
361
+ return true;
362
+ }
363
+
364
+ return false;
365
+ }
366
+
367
+ /**
368
+ * Returns if the access_token is expired.
369
+ * @return bool Returns True if the access_token is expired.
370
+ */
371
+ public function isAccessTokenExpired()
372
+ {
373
+ if (!$this->token || !isset($this->token['created'])) {
374
+ return true;
375
+ }
376
+
377
+ // If the token is set to expire in the next 30 seconds.
378
+ $expired = ($this->token['created']
379
+ + ($this->token['expires_in'] - 30)) < time();
380
+
381
+ return $expired;
382
+ }
383
+
384
+ // Gets federated sign-on certificates to use for verifying identity tokens.
385
+ // Returns certs as array structure, where keys are key ids, and values
386
+ // are PEM encoded certificates.
387
+ private function getFederatedSignOnCerts()
388
+ {
389
+ return $this->retrieveCertsFromLocation(
390
+ $this->client->getClassConfig($this, 'federated_signon_certs_url')
391
+ );
392
+ }
393
+
394
+ /**
395
+ * Retrieve and cache a certificates file.
396
+ * @param $url location
397
+ * @return array certificates
398
+ */
399
+ public function retrieveCertsFromLocation($url)
400
+ {
401
+ // If we're retrieving a local file, just grab it.
402
+ if ("http" != substr($url, 0, 4)) {
403
+ $file = file_get_contents($url);
404
+ if ($file) {
405
+ return json_decode($file, true);
406
+ } else {
407
+ throw new Google_Auth_Exception(
408
+ "Failed to retrieve verification certificates: '" .
409
+ $url . "'."
410
+ );
411
+ }
412
+ }
413
+
414
+ // This relies on makeRequest caching certificate responses.
415
+ $request = $this->client->getIo()->makeRequest(
416
+ new Google_Http_Request(
417
+ $url
418
+ )
419
+ );
420
+ if ($request->getResponseHttpCode() == 200) {
421
+ $certs = json_decode($request->getResponseBody(), true);
422
+ if ($certs) {
423
+ return $certs;
424
+ }
425
+ }
426
+ throw new Google_Auth_Exception(
427
+ "Failed to retrieve verification certificates: '" .
428
+ $request->getResponseBody() . "'.",
429
+ $request->getResponseHttpCode()
430
+ );
431
+ }
432
+
433
+ /**
434
+ * Verifies an id token and returns the authenticated apiLoginTicket.
435
+ * Throws an exception if the id token is not valid.
436
+ * The audience parameter can be used to control which id tokens are
437
+ * accepted. By default, the id token must have been issued to this OAuth2 client.
438
+ *
439
+ * @param $id_token
440
+ * @param $audience
441
+ * @return Google_Auth_LoginTicket
442
+ */
443
+ public function verifyIdToken($id_token = null, $audience = null)
444
+ {
445
+ if (!$id_token) {
446
+ $id_token = $this->token['id_token'];
447
+ }
448
+ $certs = $this->getFederatedSignonCerts();
449
+ if (!$audience) {
450
+ $audience = $this->client->getClassConfig($this, 'client_id');
451
+ }
452
+
453
+ return $this->verifySignedJwtWithCerts($id_token, $certs, $audience, self::OAUTH2_ISSUER);
454
+ }
455
+
456
+ /**
457
+ * Verifies the id token, returns the verified token contents.
458
+ *
459
+ * @param $jwt the token
460
+ * @param $certs array of certificates
461
+ * @param $required_audience the expected consumer of the token
462
+ * @param [$issuer] the expected issues, defaults to Google
463
+ * @param [$max_expiry] the max lifetime of a token, defaults to MAX_TOKEN_LIFETIME_SECS
464
+ * @return token information if valid, false if not
465
+ */
466
+ public function verifySignedJwtWithCerts(
467
+ $jwt,
468
+ $certs,
469
+ $required_audience,
470
+ $issuer = null,
471
+ $max_expiry = null
472
+ ) {
473
+ if (!$max_expiry) {
474
+ // Set the maximum time we will accept a token for.
475
+ $max_expiry = self::MAX_TOKEN_LIFETIME_SECS;
476
+ }
477
+
478
+ $segments = explode(".", $jwt);
479
+ if (count($segments) != 3) {
480
+ throw new Google_Auth_Exception("Wrong number of segments in token: $jwt");
481
+ }
482
+ $signed = $segments[0] . "." . $segments[1];
483
+ $signature = Google_Utils::urlSafeB64Decode($segments[2]);
484
+
485
+ // Parse envelope.
486
+ $envelope = json_decode(Google_Utils::urlSafeB64Decode($segments[0]), true);
487
+ if (!$envelope) {
488
+ throw new Google_Auth_Exception("Can't parse token envelope: " . $segments[0]);
489
+ }
490
+
491
+ // Parse token
492
+ $json_body = Google_Utils::urlSafeB64Decode($segments[1]);
493
+ $payload = json_decode($json_body, true);
494
+ if (!$payload) {
495
+ throw new Google_Auth_Exception("Can't parse token payload: " . $segments[1]);
496
+ }
497
+
498
+ // Check signature
499
+ $verified = false;
500
+ foreach ($certs as $keyName => $pem) {
501
+ $public_key = new Google_Verifier_Pem($pem);
502
+ if ($public_key->verify($signed, $signature)) {
503
+ $verified = true;
504
+ break;
505
+ }
506
+ }
507
+
508
+ if (!$verified) {
509
+ throw new Google_Auth_Exception("Invalid token signature: $jwt");
510
+ }
511
+
512
+ // Check issued-at timestamp
513
+ $iat = 0;
514
+ if (array_key_exists("iat", $payload)) {
515
+ $iat = $payload["iat"];
516
+ }
517
+ if (!$iat) {
518
+ throw new Google_Auth_Exception("No issue time in token: $json_body");
519
+ }
520
+ $earliest = $iat - self::CLOCK_SKEW_SECS;
521
+
522
+ // Check expiration timestamp
523
+ $now = time();
524
+ $exp = 0;
525
+ if (array_key_exists("exp", $payload)) {
526
+ $exp = $payload["exp"];
527
+ }
528
+ if (!$exp) {
529
+ throw new Google_Auth_Exception("No expiration time in token: $json_body");
530
+ }
531
+ if ($exp >= $now + $max_expiry) {
532
+ throw new Google_Auth_Exception(
533
+ sprintf("Expiration time too far in future: %s", $json_body)
534
+ );
535
+ }
536
+
537
+ $latest = $exp + self::CLOCK_SKEW_SECS;
538
+ if ($now < $earliest) {
539
+ throw new Google_Auth_Exception(
540
+ sprintf(
541
+ "Token used too early, %s < %s: %s",
542
+ $now,
543
+ $earliest,
544
+ $json_body
545
+ )
546
+ );
547
+ }
548
+ if ($now > $latest) {
549
+ throw new Google_Auth_Exception(
550
+ sprintf(
551
+ "Token used too late, %s > %s: %s",
552
+ $now,
553
+ $latest,
554
+ $json_body
555
+ )
556
+ );
557
+ }
558
+
559
+ $iss = $payload['iss'];
560
+ if ($issuer && $iss != $issuer) {
561
+ throw new Google_Auth_Exception(
562
+ sprintf(
563
+ "Invalid issuer, %s != %s: %s",
564
+ $iss,
565
+ $issuer,
566
+ $json_body
567
+ )
568
+ );
569
+ }
570
+
571
+ // Check audience
572
+ $aud = $payload["aud"];
573
+ if ($aud != $required_audience) {
574
+ throw new Google_Auth_Exception(
575
+ sprintf(
576
+ "Wrong recipient, %s != %s:",
577
+ $aud,
578
+ $required_audience,
579
+ $json_body
580
+ )
581
+ );
582
+ }
583
+
584
+ // All good.
585
+ return new Google_Auth_LoginTicket($envelope, $payload);
586
+ }
587
+ }
lib/Google/Auth/Simple.php ADDED
@@ -0,0 +1,92 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Auth/Abstract.php";
19
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Http/Request.php";
20
+
21
+ /**
22
+ * Simple API access implementation. Can either be used to make requests
23
+ * completely unauthenticated, or by using a Simple API Access developer
24
+ * key.
25
+ * @author Chris Chabot <chabotc@google.com>
26
+ * @author Chirag Shah <chirags@google.com>
27
+ */
28
+ class Google_Auth_Simple extends Google_Auth_Abstract
29
+ {
30
+ private $key = null;
31
+ private $client;
32
+
33
+ public function __construct(Google_Client $client, $config = null)
34
+ {
35
+ $this->client = $client;
36
+ }
37
+
38
+ /**
39
+ * Perform an authenticated / signed apiHttpRequest.
40
+ * This function takes the apiHttpRequest, calls apiAuth->sign on it
41
+ * (which can modify the request in what ever way fits the auth mechanism)
42
+ * and then calls apiCurlIO::makeRequest on the signed request
43
+ *
44
+ * @param Google_Http_Request $request
45
+ * @return Google_Http_Request The resulting HTTP response including the
46
+ * responseHttpCode, responseHeaders and responseBody.
47
+ */
48
+ public function authenticatedRequest(Google_Http_Request $request)
49
+ {
50
+ $request = $this->sign($request);
51
+ return $this->io->makeRequest($request);
52
+ }
53
+
54
+ public function authenticate($code)
55
+ {
56
+ throw new Google_Auth_Exception("Simple auth does not exchange tokens.");
57
+ }
58
+
59
+ public function setAccessToken($accessToken)
60
+ {
61
+ /* noop*/
62
+ }
63
+
64
+ public function getAccessToken()
65
+ {
66
+ return null;
67
+ }
68
+
69
+ public function createAuthUrl($scope)
70
+ {
71
+ return null;
72
+ }
73
+
74
+ public function refreshToken($refreshToken)
75
+ {
76
+ /* noop*/
77
+ }
78
+
79
+ public function revokeToken()
80
+ {
81
+ /* noop*/
82
+ }
83
+
84
+ public function sign(Google_Http_Request $request)
85
+ {
86
+ $key = $this->client->getClassConfig($this, 'developer_key');
87
+ if ($key) {
88
+ $request->setQueryParam('key', $key);
89
+ }
90
+ return $request;
91
+ }
92
+ }
lib/Google/Cache/Abstract.php ADDED
@@ -0,0 +1,53 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Abstract storage class
20
+ *
21
+ * @author Chris Chabot <chabotc@google.com>
22
+ */
23
+ abstract class Google_Cache_Abstract
24
+ {
25
+
26
+ abstract public function __construct(Google_Client $client);
27
+
28
+ /**
29
+ * Retrieves the data for the given key, or false if they
30
+ * key is unknown or expired
31
+ *
32
+ * @param String $key The key who's data to retrieve
33
+ * @param boolean|int $expiration Expiration time in seconds
34
+ *
35
+ */
36
+ abstract public function get($key, $expiration = false);
37
+
38
+ /**
39
+ * Store the key => $value set. The $value is serialized
40
+ * by this function so can be of any type
41
+ *
42
+ * @param string $key Key of the data
43
+ * @param string $value data
44
+ */
45
+ abstract public function set($key, $value);
46
+
47
+ /**
48
+ * Removes the key/data pair for the given $key
49
+ *
50
+ * @param String $key
51
+ */
52
+ abstract public function delete($key);
53
+ }
lib/Google/Cache/Apc.php ADDED
@@ -0,0 +1,73 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2010 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Cache/Abstract.php";
19
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Cache/Exception.php";
20
+
21
+ /**
22
+ * A persistent storage class based on the APC cache, which is not
23
+ * really very persistent, as soon as you restart your web server
24
+ * the storage will be wiped, however for debugging and/or speed
25
+ * it can be useful, and cache is a lot cheaper then storage.
26
+ *
27
+ * @author Chris Chabot <chabotc@google.com>
28
+ */
29
+ class Google_Cache_Apc extends Google_Cache_Abstract
30
+ {
31
+ public function __construct(Google_Client $client)
32
+ {
33
+ if (! function_exists('apc_add') ) {
34
+ throw new Google_Cache_Exception("Apc functions not available");
35
+ }
36
+ }
37
+
38
+ /**
39
+ * @inheritDoc
40
+ */
41
+ public function get($key, $expiration = false)
42
+ {
43
+ $ret = apc_fetch($key);
44
+ if ($ret === false) {
45
+ return false;
46
+ }
47
+ if (is_numeric($expiration) && (time() - $ret['time'] > $expiration)) {
48
+ $this->delete($key);
49
+ return false;
50
+ }
51
+ return $ret['data'];
52
+ }
53
+
54
+ /**
55
+ * @inheritDoc
56
+ */
57
+ public function set($key, $value)
58
+ {
59
+ $rc = apc_store($key, array('time' => time(), 'data' => $value));
60
+ if ($rc == false) {
61
+ throw new Google_Cache_Exception("Couldn't store data");
62
+ }
63
+ }
64
+
65
+ /**
66
+ * @inheritDoc
67
+ * @param String $key
68
+ */
69
+ public function delete($key)
70
+ {
71
+ apc_delete($key);
72
+ }
73
+ }
lib/Google/Cache/Exception.php ADDED
@@ -0,0 +1,21 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2013 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Exception.php";
18
+
19
+ class Google_Cache_Exception extends Google_Exception
20
+ {
21
+ }
lib/Google/Cache/File.php ADDED
@@ -0,0 +1,145 @@
1
+ <?php
2
+ /*
3
+ * Copyright 2008 Google Inc.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Cache/Abstract.php";
19
+ require_once $GLOBALS['iwp_mmb_plugin_dir']."/lib/Google/Cache/Exception.php";
20
+
21
+ /*
22
+ * This class implements a basic on disk storage. While that does
23
+ * work quite well it's not the most elegant and scalable solution.
24
+ * It will also get you into a heap of trouble when you try to run
25
+ * this in a clustered environment.
26
+ *
27
+ * @author Chris Chabot <chabotc@google.com>
28
+ */
29
+ class Google_Cache_File extends Google_Cache_Abstract
30
+ {
31
+ const MAX_LOCK_RETRIES = 10;
32
+ private $path;
33
+ private $fh;
34
+
35
+ public function __construct(Google_Client $client)
36
+ {
37
+ $this->path = $client->getClassConfig($this, 'directory');
38
+ }
39
+
40
+ public function get($key, $expiration = false)
41
+ {
42
+ $storageFile = $this->getCacheFile($key);
43
+ $data = false;
44
+
45
+ if (!file_exists($storageFile)) {
46
+ return false;
47
+ }
48
+
49
+ if ($expiration) {
50
+ $mtime = filemtime($storageFile);
51
+ if (($now - $mtime) >= $expiration) {
52
+ $this->delete($key);
53
+ return false;
54
+ }
55
+ }
56
+
57
+ if ($this->acquireReadLock($storageFile)) {
58
+ $data = fread($this->fh, filesize($storageFile));
59
+ $data = unserialize($data);
60
+ $this->unlock($storageFile);
61
+ }
62
+
63
+ return $data;
64
+ }
65
+
66
+ public function set($key, $value)
67
+ {
68
+ $storageFile = $this->getWriteableCacheFile($key);
69
+ if ($this->acquireWriteLock($storageFile)) {
70
+ // We serialize the whole request object, since we don't only want the
71
+ // responseContent but also the postBody used, headers, size, etc.
72
+ $data = serialize($value);
73
+ $result = fwrite($this->fh, $data);
74
+ $this->unlock($storageFile);
75
+ }
76
+ }
77
+
78
+ public function delete($key)
79
+ {
80
+ $file = $this->getCacheFile($key);
81
+ if (file_exists($file) && !unlink($file)) {
82
+ throw new Google_Cache_Exception("Cache file could not be deleted");
83
+ }
84
+ }
85
+
86
+ private function getWriteableCacheFile($file)
87
+ {
88
+ return $this->getCacheFile($file, true);
89
+ }
90
+
91
+ private function getCacheFile($file, $forWrite = false)
92
+ {
93
+ return $this->getCacheDir($file, $forWrite) . '/' . md5($file);
94
+ }
95
+
96
+ private function getCacheDir($file, $forWrite)
97
+ {
98
+ // use the first 2 characters of the hash as a directory prefix
99
+ // this should prevent slowdowns due to huge directory listings
100
+ // and thus give some basic amount of scalability
101
+ $storageDir = $this->path . '/' . substr(md5($file), 0, 2);
102
+ if ($forWrite && ! is_dir($storageDir)) {
103
+ if (! mkdir($storageDir, 0755, true)) {
104
+ throw new Google_Cache_Exception("Could not create storage directory: $storageDir");
105
+ }
106
+ }
107
+ return $storageDir;
108
+ }
109
+
110
+ private function acquireReadLock($storageFile)
111
+ {
112
+ return $this->acquireLock(LOCK_SH, $storageFile);
113
+ }
114
+
115
+ private function acquireWriteLock($storageFile)
116
+ {
117
+ $rc = $this->acquireLock(LOCK_EX, $storageFile);
118
+ if (!$rc) {
119
+ $this->delete($storageFile);
120
+ }
121
+ return $rc;
122
+ }
123
+
124
+ private function acquireLock($type, $storageFile)
125
+ {
126
+ $mode = $type == LOCK_EX ? "w" : "r";
127
+ $this->fh = fopen($storageFile, $mode);
128
+ $count = 0;
129
+ while (!flock($this->fh, $type | LOCK_NB)) {
130
+ // Sleep for 10ms.
131
+ usleep(10000);
132
+ if (++$count < self::MAX_LOCK_RETRIES) {
133
+ return false;
134
+ }
135
+ }
136
+ return true;
137
+ }
138
+
139
+ public function unlock($storageFile)
140
+ {
141
+ if ($this->fh) {
142
+ flock($this->fh, LOCK_UN);
143
+ }
144
+ }
145
+ }
lib/Google/Cache/Memcache.php ADDED
@@ -0,0 +1,137 @@