2
2
3
3
declare (strict_types=1 );
4
4
5
+ /**
6
+ * Build a query for a contribution graph
7
+ *
8
+ * @param string $user GitHub username to get graphs for
9
+ * @param int $year Year to get graph for
10
+ *
11
+ * @return string GraphQL query
12
+ */
13
+ function buildContributionGraphQuery (string $ user , int $ year )
14
+ {
15
+ $ start = "$ year-01-01T00:00:00Z " ;
16
+ $ end = "$ year-12-31T23:59:59Z " ;
17
+ return "query {
18
+ user(login: \"$ user \") {
19
+ contributionsCollection(from: \"$ start \", to: \"$ end \") {
20
+ contributionCalendar {
21
+ totalContributions
22
+ weeks {
23
+ contributionDays {
24
+ contributionCount
25
+ date
26
+ }
27
+ }
28
+ }
29
+ }
30
+ }
31
+ } " ;
32
+ }
33
+
5
34
/**
6
35
* Get all HTTP request responses for user's contributions
7
36
*
@@ -17,23 +46,7 @@ function getContributionGraphs(string $user): array
17
46
$ requests = [];
18
47
foreach ($ contributionYears as $ year ) {
19
48
// create query for year
20
- $ start = "$ year-01-01T00:00:00Z " ;
21
- $ end = "$ year-12-31T23:59:59Z " ;
22
- $ query = "query {
23
- user(login: \"$ user \") {
24
- contributionsCollection(from: \"$ start \", to: \"$ end \") {
25
- contributionCalendar {
26
- totalContributions
27
- weeks {
28
- contributionDays {
29
- contributionCount
30
- date
31
- }
32
- }
33
- }
34
- }
35
- }
36
- } " ;
49
+ $ query = buildContributionGraphQuery ($ user , $ year );
37
50
// create curl request
38
51
$ requests [$ year ] = getGraphQLCurlHandle ($ query );
39
52
}
@@ -47,16 +60,29 @@ function getContributionGraphs(string $user): array
47
60
do {
48
61
curl_multi_exec ($ multi , $ running );
49
62
} while ($ running );
63
+ // collect responses from last to first
64
+ $ response = [];
65
+ foreach ($ requests as $ year => $ request ) {
66
+ $ contents = curl_multi_getcontent ($ request );
67
+ $ decoded = json_decode ($ contents );
68
+ // if response is empty or invalid, retry request one time
69
+ if (empty ($ decoded )) {
70
+ $ query = buildContributionGraphQuery ($ user , $ year );
71
+ $ request = getGraphQLCurlHandle ($ query );
72
+ $ contents = curl_exec ($ request );
73
+ if ($ contents === false ) {
74
+ error_log ("Failed to decode response for $ user's $ year contributions after 2 attempts. " );
75
+ continue ;
76
+ }
77
+ $ decoded = json_decode ($ contents );
78
+ }
79
+ array_unshift ($ response , $ decoded );
80
+ }
50
81
// close the handles
51
82
foreach ($ requests as $ request ) {
52
83
curl_multi_remove_handle ($ multi , $ request );
53
84
}
54
85
curl_multi_close ($ multi );
55
- // collect responses from last to first
56
- $ response = [];
57
- foreach ($ requests as $ request ) {
58
- array_unshift ($ response , json_decode (curl_multi_getcontent ($ request )));
59
- }
60
86
return $ response ;
61
87
}
62
88
@@ -190,17 +216,15 @@ function getContributionYears(string $user): array
190
216
*/
191
217
function getContributionDates (array $ contributionGraphs ): array
192
218
{
193
- // get contributions from HTML
194
219
$ contributions = [];
195
220
$ today = date ("Y-m-d " );
196
221
$ tomorrow = date ("Y-m-d " , strtotime ("tomorrow " ));
222
+ // sort contribution calendars by year key
223
+ ksort ($ contributionGraphs );
197
224
foreach ($ contributionGraphs as $ graph ) {
198
225
if (!empty ($ graph ->errors )) {
199
226
throw new AssertionError ($ graph ->data ->errors [0 ]->message , 502 );
200
227
}
201
- if (empty ($ graph )) {
202
- continue ;
203
- }
204
228
$ weeks = $ graph ->data ->user ->contributionsCollection ->contributionCalendar ->weeks ;
205
229
foreach ($ weeks as $ week ) {
206
230
foreach ($ week ->contributionDays as $ day ) {
0 commit comments