-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGoogleDriveSpreadsheets.php
144 lines (116 loc) · 7.05 KB
/
GoogleDriveSpreadsheets.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<?php
//With help from https://gist.github.com/karlkranich/de225928665dc6b83667
require_once ("google-api-php-client/vendor/autoload.php");
include_once ("google-api-php-client/examples/templates/base.php");
include_once ("OtherStuff.php");
class GoogleSpreadsheet {
public function updateRow($emailAddress, $timeInterval, $paymentAmount) {
global $fileId;
$client = $this -> getGoogleClient();
//Is the following needed? $service is never used.
//$service = new Google_Service_Sheets($client);
$tokenArray = $client -> fetchAccessTokenWithAssertion();
$accessToken = $tokenArray["access_token"];
$spreadsheetRows = $this -> queryFileByEmailAddress($fileId, $emailAddress, $accessToken);
$tableXML = simplexml_load_string($spreadsheetRows);
//Loop over this, because family memberships might have multiple cards under the same email
foreach ($tableXML -> entry as $entry) {
//Look for the "Expiration Date" column, add time to it, then save the row back to the Google spreadsheet
//Again, note that all the column names need to be lowercased for some reason.
$column = $this -> findColumnFromEntry("expirationdate", $entry);
if (isset($column)) {
$expDate = $this -> parseDateFromColumn($column);
$newExpDate = $this -> updateExpirationDate($expDate, $timeInterval);
$rowId = $entry -> id;
//$rowId contains an entire url, where the last param contains the actual id. Strip out the real id.
$rowId = substr($rowId, strrpos($rowId, '/') + 1);
$expDate = $expDate -> format("m/d/Y");
$this -> updateRowInFile($fileId, $rowId, $newExpDate, $accessToken);
$this -> addRowToAuditFile($emailAddress, $expDate, $newExpDate, $paymentAmount, $accessToken);
}
$entry = array_pop($tableXML);
}
}
function findColumnFromEntry($columnName, $entry) {
foreach ($entry -> children('gsx', TRUE) as $column)
if ($column -> getName() === $columnName)
return $column;
return null;
}
function parseDateFromColumn($column) {
$expDate = date_create_from_format("m/d/Y", $column);
//Account for Y2K. Dates manually entered in the spreadsheet may have two-digit year values.
$longTimeAgo = new DateTime('1970-01-01');
if ($expDate < $longTimeAgo) {
$expDate = date_create_from_format('m/d/y', $column);
}
return $expDate;
}
function updateExpirationDate($expDate, $timeInterval) {
$newExpiration = clone $expDate;
$today = new DateTime();
if ($expDate < $today) {
$newExpiration = $today;
}
if ($timeInterval === "month") {
$newExpiration = $newExpiration -> add(new DateInterval("P1M"));
} else if ($timeInterval === "year") {
$newExpiration = $newExpiration -> add(new DateInterval("P1Y"));
} else if ($timeInterval === "removeMonth") {
$newExpiration = $newExpiration -> sub(new DateInterval("P1M"));
} else if ($timeInterval === "removeYear") {
$newExpiration = $newExpiration -> sub(new DateInterval("P1Y"));
}
return $newExpiration -> format("m/d/Y");
}
function queryFileByEmailAddress($fileId, $emailAddress, $accessToken) {
$url = "https://spreadsheets.google.com/feeds/list/$fileId/od6/private/full?sq=quantity>9";
//We're going to query for a row with a matching email, since Paypal uses email as a unique id
//Be careful with the query; google's api's suck. Must be paypalemail="$emailAddress";. Note the use of lowercase column names, and the double quotes.
$queryByEmail = "paypalemail=\"$emailAddress\"";
$headers = ["Authorization" => "Bearer $accessToken", "GData-Version" => "3.0"];
$httpClient = new GuzzleHttp\Client(['headers' => $headers]);
$resp = $httpClient -> request('GET', $url, ['query' => ['sq' => $queryByEmail]]);
$body = $resp -> getBody() -> getContents();
return $body;
}
function updateRowInFile($fileId, $rowId, $expDate, $accessToken) {
$url = "https://spreadsheets.google.com/feeds/list/$fileId/od6/private/full/$rowId";
$headers = ["Authorization" => "Bearer $accessToken", 'GData-Version' => '3.0', 'Content-Type' => 'application/atom+xml', 'If-Match' => '*'];
$postBody = "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:gsx=\"http://schemas.google.com/spreadsheets/2006/extended\" xmlns:gd=\"http://schemas.google.com/g/2005\"><id>https://spreadsheets.google.com/feeds/list/$fileId/od6/$rowId</id><gsx:expirationdate>$expDate</gsx:expirationdate></entry>";
$httpClient = new GuzzleHttp\Client(['headers' => $headers]);
$resp = $httpClient -> request('PUT', $url, ['body' => $postBody]);
$body = $resp -> getBody() -> getContents();
$code = $resp -> getStatusCode();
if ($code != 200) {
$reason = $resp -> getReasonPhrase();
throw new Exception("Couldn't update spreadsheet - got $code : $reason");
}
}
function addRowToAuditFile($emailAddress, $oldExpiration, $newExpiration, $amount, $accessToken) {
global $auditFileId;
$now = new DateTime();
$now = $now -> format("m/d/Y");
$url = "https://spreadsheets.google.com/feeds/list/$auditFileId/od6/private/full";
$headers = ["Authorization" => "Bearer $accessToken", 'Content-Type' => 'application/atom+xml'];
$postBody = "<entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:gsx=\"http://schemas.google.com/spreadsheets/2006/extended\"><gsx:paypalemail>$emailAddress</gsx:paypalemail><gsx:amountpaid>$amount</gsx:amountpaid><gsx:oldexpirationdate>$oldExpiration</gsx:oldexpirationdate><gsx:newexpirationdate>$newExpiration</gsx:newexpirationdate><gsx:processeddate>$now</gsx:processeddate></entry>";
$httpClient = new GuzzleHttp\Client(['headers' => $headers]);
$resp = $httpClient -> request('POST', $url, ['body' => $postBody]);
$body = $resp -> getBody() -> getContents();
$code = $resp -> getStatusCode();
if ($code < 200 && $code >= 300) {
//Accept any 200 response. I think it actually returns a 201 Created.
$reason = $resp->getReasonPhrase();
throw new Exception("Couldn't add a row to the audit sheet - got $code : $reason");
}
}
function getGoogleClient() {
putenv("GOOGLE_APPLICATION_CREDENTIALS=service-account-credentials.json");
$client = new Google_Client();
$client -> useApplicationDefaultCredentials();
$client -> setApplicationName("Payment_Notifications");
$client -> setScopes(['https://www.googleapis.com/auth/drive', 'https://spreadsheets.google.com/feeds']);
//$client->setDeveloperKey("");
return $client;
}
}