Completed
Push — master ( 380473...b1e8a8 )
by Renato
02:46
created

Github::setCommitFiles()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 29
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 29
rs 8.5806
c 0
b 0
f 0
cc 4
eloc 22
nc 6
nop 4
1
<?php
2
3
namespace GitScrum\Classes;
4
5
use Auth;
6
use GitScrum\Models\Branch;
7
use GitScrum\Models\Commit;
8
use GitScrum\Models\ConfigStatus;
9
use GitScrum\Models\User;
10
use GitScrum\Models\Issue;
11
use GitScrum\Models\Organization;
12
use GitScrum\Models\ProductBacklog;
13
use Carbon\Carbon;
14
use GitScrum\Libraries\Phpcs;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, GitScrum\Classes\Phpcs.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
15
16
class Github
17
{
18
    public function templateRepository($repo, $slug = false)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
19
    {
20
        return (object) [
21
            'github_id' => $repo->id,
22
            'organization_id' => $this->organization($repo->owner->login),
23
            'organization_title' => $repo->owner->login,
24
            'slug' => $slug ? $slug : Helper::slug($repo->name),
25
            'title' => $repo->name,
26
            'fullname' => $repo->full_name,
27
            'is_private' => $repo->private,
28
            'html_url' => $repo->html_url,
29
            'description' => $repo->description,
30
            'fork' => $repo->fork,
31
            'url' => $repo->url,
32
            'since' => Carbon::parse($repo->created_at)->toDateTimeString(),
33
            'pushed_at' => Carbon::parse($repo->pushed_at)->toDateTimeString(),
34
            'ssh_url' => $repo->ssh_url,
35
            'clone_url' => $repo->clone_url,
36
            'homepage' => $repo->homepage,
37
            'default_branch' => $repo->default_branch,
38
        ];
39
    }
40
41
    public function readRepositories()
42
    {
43
        $repos = collect($this->request('https://api.github.com/user/repos'));
44
45
        $response = $repos->map(function ($repo) {
46
            return $this->templateRepository($repo);
47
        });
48
49
        return $response;
50
    }
51
52
    public function createOrUpdateRepository($owner, $obj, $oldTitle = null)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
53
    {
54
        $params = [
55
            'name' => str_slug($obj->title, '-'),
56
            'description' => $obj->description,
57
        ];
58
59
        if (is_null($oldTitle)) {
60
            $response = $this->request('https://api.github.com/orgs/'.$owner.'/repos', true, 'POST', $params);
61
        } else {
62
            $oldTitle = str_slug($oldTitle, '-');
63
            $response = $this->request('https://api.github.com/repos/'.$owner.DIRECTORY_SEPARATOR.$oldTitle, true, 'POST', $params);
64
        }
65
66
        return (object) $response;
67
    }
68
69
    public function organization($login)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
70
    {
71
        $orgData = $this->request('https://api.github.com/orgs/'.$login);
72
73
        if (!isset($orgData->id)) {
74
            $orgData = $this->request('https://api.github.com/users/'.$login);
75
        }
76
77
        $data = [
78
            'github_id' => @$orgData->id,
79
            'username' => @$orgData->login,
80
            'url' => @$orgData->url,
81
            'repos_url' => @$orgData->repos_url,
82
            'events_url' => @$orgData->events_url,
83
            'hooks_url' => @$orgData->hooks_url,
84
            'issues_url' => @$orgData->issues_url,
85
            'members_url' => @$orgData->members_url,
86
            'public_members_url' => @$orgData->public_members_url,
87
            'avatar_url' => @$orgData->avatar_url,
88
            'description' => @$orgData->description,
89
            'title' => @$orgData->name,
90
            'blog' => @$orgData->blog,
91
            'location' => @$orgData->location,
92
            'email' => @$orgData->email,
93
            'public_repos' => @$orgData->public_repos,
94
            'html_url' => @$orgData->html_url,
95
            'total_private_repos' => @$orgData->total_private_repos,
96
            'since' => @Carbon::parse($orgData->created_at)->toDateTimeString(),
97
            'disk_usage' => @$orgData->disk_usage,
98
        ];
99
100
        try {
101
            $organization = Organization::create($data);
102
        } catch (\Illuminate\Database\QueryException $e) {
103
            $organization = Organization::where('username', $orgData->login)->first();
104
        }
105
106
        $organization->users()->sync([Auth::id()]);
107
108
        return $organization->id;
109
    }
110
111
    public function readCollaborators($owner, $repo)
112
    {
113
        $collaborators = $this->request('https://api.github.com/repos/'.$owner.'/'.$repo.'/collaborators');
114
        foreach ($collaborators as $collaborator) {
115
            if (isset($collaborator->id)) {
116
                $data = [
117
                    'github_id' => $collaborator->id,
118
                    'username' => $collaborator->login,
119
                    'name' => $collaborator->login,
120
                    'avatar' => $collaborator->avatar_url,
121
                    'html_url' => $collaborator->html_url,
122
                    'email' => null,
123
                    'remember_token' => null,
124
                    'bio' => null,
125
                    'location' => null,
126
                    'blog' => null,
127
                    'since' => null,
128
                    'token' => null,
129
                    'position_held' => null,
130
                ];
131
132
                try {
133
                    $user = User::create($data);
134
                } catch (\Exception $e) {
135
                    $user = User::where('username', $collaborator->login)->first();
136
                }
137
138
                $userId[] = $user->id;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$userId was never initialized. Although not strictly required by PHP, it is generally a good practice to add $userId = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
139
140
            }
141
        }
142
143
        $organization = Organization::where('username', $owner)->first()->users();
144
        $organization->sync($userId);
0 ignored issues
show
Bug introduced by
The variable $userId does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
145
146
    }
147
148
    public function createBranches($owner, $product_backlog_id, $repo)
149
    {
150
        $y = 0;
151
        for ($i = 1; $i > $y; ++$i) {
152
            $branches = $this->request('https://api.github.com/repos/'.$owner.DIRECTORY_SEPARATOR.$repo.'/branches?page='.$i);
153
            foreach ($branches as $branch) {
154
                $data = [
155
                    'product_backlog_id' => $product_backlog_id,
156
                    'title' => $branch->name,
157
                    'sha' => $branch->commit->sha,
158
                ];
159
                Branch::create($data);
160
            }
161
            if (count($branches) < 30) {
162
                $y = $i + 2;
163
            }
164
        }
165
    }
166
167
    public function readIssues()
168
    {
169
        $repos = ProductBacklog::all();
170
171
        foreach ($repos as $repo) {
172
            $issues = $this->request('https://api.github.com/repos/'.$repo->organization->username.DIRECTORY_SEPARATOR.$repo->title.'/issues?state=all');
173
174
            foreach ($issues as $issue) {
175
                $user = User::where('username', $issue->user->login)->first();
176
177
                $data = [
178
                    'github_id' => $issue->id,
179
                    'user_id' => isset($user_id) ? $user->id : Auth::user()->id,
180
                    'product_backlog_id' => $repo->id,
181
                    'effort' => 0,
182
                    'config_issue_effort_id' => 1,
183
                    'issue_type_id' => 1,
184
                    'number' => $issue->number,
185
                    'title' => $issue->title,
186
                    'description' => $issue->body,
187
                    'state' => $issue->state,
188
                    'html_url' => $issue->html_url,
189
                    'created_at' => $issue->created_at,
190
                    'updated_at' => $issue->updated_at,
191
                ];
192
193
                if (!is_null($issue->closed_at)) {
194
                    $data['closed_at'] = Carbon::parse($issue->closed_at)->format('Y-m-d h:m:s');
195
                    $data['closed_user_id'] = $data['user_id'];
196
                    $data['config_status_id'] = ConfigStatus::where('type', 'issue')
197
                        ->where('is_closed', 1)->first()->id;
198
                }
199
200
                if (!Issue::where('github_id', $issue->id)->first()) {
201
                    Issue::create($data)->users()->sync([$data['user_id']]);
202
                }
203
                //foreach ($issue->assignees as $assign) {
204
                //    User::where('github_id', $assign->id)->first()->issues()->sync([$issueId], false);
205
                //}
206
            }
207
        }
208
    }
209
210
    public function createOrUpdateIssue($obj)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
211
    {
212
        $params = [
213
            'title' => $obj->title,
214
            'body' => $obj->description,
215
        ];
216
217
        $response = $this->request('https://api.github.com/repos/'.
218
            $obj->productBacklog->organization->username.DIRECTORY_SEPARATOR.
219
            $obj->productBacklog->title.'/issues'.(isset($obj->number) ? DIRECTORY_SEPARATOR.$obj->number : ''),
220
            true, 'POST', $params);
221
222
        return (object) $response;
223
    }
224
225
    public function createOrUpdateIssueComment($obj, $verb = 'POST')
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
226
    {
227
        $params = [
228
            'body' => $obj->comment,
229
        ];
230
231
        $response = $this->request('https://api.github.com/repos/'.
232
            $obj->issue->productBacklog->organization->username.DIRECTORY_SEPARATOR.
233
            $obj->issue->productBacklog->title.'/issues'.(isset($obj->github_id) ? '' : DIRECTORY_SEPARATOR.$obj->issue->number).'/comments'.
234
            (isset($obj->github_id) ? DIRECTORY_SEPARATOR.$obj->github_id : ''),
235
            true, $verb, $params);
236
237
        return (object) $response;
238
    }
239
240
    public function deleteIssueComment($obj)
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
241
    {
242
        return $this->createOrUpdateIssueComment($obj, 'DELETE');
243
    }
244
245
    private function request($url, $auth = true, $customRequest = null, $postFields = null)
246
    {
247
        $user = Auth::user();
248
        $ch = curl_init();
249
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 5.1; rv:31.0) Gecko/20100101 Firefox/31.0');
250
        curl_setopt($ch, CURLOPT_URL, $url);
251
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
252
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
253
        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
254
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
255
256
        if (env('PROXY_PORT')) {
257
            curl_setopt($ch, CURLOPT_PROXYPORT, env('PROXY_PORT'));
258
            curl_setopt($ch, CURLOPT_PROXYTYPE, env('PROXY_METHOD'));
259
            curl_setopt($ch, CURLOPT_PROXY, env('PROXY_SERVER'));
260
        }
261
262
        if (env('PROXY_USER')) {
263
            curl_setopt($ch, CURLOPT_PROXYUSERPWD, env('PROXY_USER').':'.env('PROXY_USER'));
264
        }
265
266
        if (!is_null($postFields)) {
267
            $postFields = json_encode($postFields);
268
            curl_setopt($ch, CURLOPT_POST, true);
269
            curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);
270
            curl_setopt($ch, CURLOPT_HTTPHEADER,  ['Content-Type: application/json',
271
                'Content-Length: '.strlen($postFields), ]);
272
        }
273
274
        if (!is_null($customRequest)) {
275
            curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $customRequest); //'PATCH'
276
        }
277
278
        if ($auth && isset($user->username)) {
279
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
280
            curl_setopt($ch, CURLOPT_USERPWD, $user->username.':'.$user->token);
281
        }
282
283
        $status_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
0 ignored issues
show
Unused Code introduced by
$status_code is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
284
        $result = curl_exec($ch);
285
        curl_close($ch);
286
287
        return json_decode($result);
288
    }
289
290
    /*
291
    public function organizations(){
292
        $this->request('https://api.github.com/user/orgs');
293
    }
294
295
    public function repositories($org){
296
        ///orgs/:org/repos
297
        return $this->request('https://api.github.com/orgs/'.$org.'/repos');
298
    }
299
    */
300
301
    public function setCommits($owner, $repo, $branch, $since = null)
302
    {
303
        ////repos/:owner/:repo/commits?sha=branchname
304
        $y = 0;
305
        for ($i = 1; $i > $y; ++$i) {
306
            $commits = $this->request('https://api.github.com/repos/'.$owner.DIRECTORY_SEPARATOR.$repo.'/commits?page='.$i.
307
            '&sha='.$branch.(is_null($since) ? '' : '&since='.$since));
308
            $branch = Branch::join('product_backlogs', 'branches.product_backlog_id', '=', 'repositories.id')
309
                            ->where('branches.name', $branch)
310
                            ->where('product_backlogs.name', $repo)
311
                            ->select('branches.id AS branch_id', 'repositories.id AS product_backlog_id')->first();
312
            $CommitRepository = new CommitRepository();
313
            foreach ($commits as $commit) {
314
                try {
315
                    $user = User::where('github_id', $commit->author->id)->first();
316
                    $userId = $user->id;
317
                } catch (\Exception $e) {
318
                    $userId = 0;
319
                }
320
                try {
321
                    if (isset($commit->sha)) {
322
                        $data = [
323
                            'product_backlog_id' => $branch->product_backlog_id,
324
                            'branch_id' => $branch->branch_id,
325
                            'user_id' => $userId,
326
                            'sha' => $commit->sha,
327
                            'url' => $commit->url,
328
                            'message' => $commit->commit->message,
329
                            'html_url' => $commit->html_url,
330
                            'date' => $commit->commit->author->date,
331
                            'tree_sha' => $commit->commit->tree->sha,
332
                            'tree_url' => $commit->commit->tree->url,
333
                        ];
334
                        $commitData = $CommitRepository->add($data);
335
                        $this->setCommitFiles($owner, $repo, $commitData->sha, $commitData);
336
                    }
337
                } catch (\Exception $e) {
338
                    dd($data, $commit);
339
                }
340
            }
341
            if (count($commits) < 30) {
342
                $y = $i + 2;
343
            }
344
        }
345
    }
346
347
    public function setCommitFiles($owner, $repo, $sha, $objCommit)
348
    {
349
        // /repos/:owner/:repo/commits/:sha
350
        $commits = $this->request('https://api.github.com/repos/'.$owner.DIRECTORY_SEPARATOR.$repo.'/commits/'.$sha);
351
        $Phpcs = new Phpcs();
0 ignored issues
show
Unused Code introduced by
$Phpcs is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
352
        $CommitRepository = new CommitRepository();
353
        foreach ($commits->files as $commit) {
354
            try {
355
                $contents = $this->request($commit->contents_url);
356
                $fileRaw = file_get_contents($contents->download_url);
357
                $data = [
358
                    'commit_id' => $objCommit->id,
359
                    'sha' => $commit->sha,
360
                    'filename' => $commit->filename,
361
                    'status' => $commit->status,
362
                    'additions' => $commit->additions,
363
                    'deletions' => $commit->deletions,
364
                    'changes' => $commit->changes,
365
                    'raw_url' => $commit->raw_url,
366
                    'raw' => $fileRaw,
367
                    'patch' => (isset($commit->patch) ? $commit->patch : ''),
368
                ];
369
                $commitData = $CommitRepository->addFile($data);
0 ignored issues
show
Unused Code introduced by
$commitData is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
370
                //$Phpcs->init($fileRaw, $commitData->id);
371
            } catch (\Exception $e) {
372
                echo 'erro files ... ';
373
            }
374
        }
375
    }
376
377
    public function getCommit($owner, $repo, $sha)
378
    {
379
        // /repos/:owner/:repo/commits/:sha
380
        $commits = $this->request('https://api.github.com/repos/'.$owner.DIRECTORY_SEPARATOR.$repo.'/commits/'.$sha);
381
        dd($commits);
382
        /*
383
        foreach ($commits as $commit) {
384
            $data = [
385
                'commit_id'=>$objCommit->id,
386
                'sha'=>,
387
                'filename'=>,
388
                'status'=>,
389
                'additions'=>,
390
                'deletetions'=>,
391
                'changes'=>,
392
                'raw_url'=>,
393
                'patch'=>
394
            ];
395
        }*/
396
    }
397
398
    public function setPullRequest($owner, $repo)
399
    {
400
        ///repos/:owner/:repo/pulls
401
        $pulls = $this->request('https://api.github.com/repos/'.$owner.DIRECTORY_SEPARATOR.$repo.'/pulls');
402
        $repository = Repository::where('name', $repo)->first();
403
        $PullRequestRepository = new PullRequestRepository();
404
        foreach ($pulls as $pull) {
405
            $branch = Branch::where('name', $pull->head->ref)->first();
406
            try {
407
                $user = User::where('github_id', $pull->user->id)->first();
408
                $userId = $user->id;
409
            } catch (\Exception $e) {
410
                $userId = 0;
411
            }
412
413
            try {
414
                $headBranchId = $branch->id;
415
            } catch (\Exception $e) {
0 ignored issues
show
Unused Code introduced by
catch (\Exception $e) { $headBranchId = 0; } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
416
                $headBranchId = 0;
417
            }
418
419
            try {
420
                $branch = Branch::where('name', $pull->base->ref)->first();
421
                $baseBranchId = $branch->id;
422
            } catch (\Exception $e) {
423
                $baseBranchId = 0;
424
            }
425
426
            $data = [
427
                'github_id' => $pull->id,
428
                'number' => $pull->number,
429
                'user_id' => $userId,
430
                'product_backlog_id' => $repository->id,
431
                'url' => $pull->url,
432
                'html_url' => $pull->html_url,
433
                'issue_url' => $pull->issue_url,
434
                'commits_url' => $pull->commits_url,
435
                'state' => $pull->state,
436
                'title' => $pull->title,
437
                'body' => $pull->body,
438
                'github_created_at' => $pull->created_at,
439
                'github_updated_at' => $pull->updated_at,
440
                'head_branch_id' => $headBranchId,
441
                'base_branch_id' => $baseBranchId,
442
            ];
443
444
            $pull = $PullRequestRepository->add($data);
445
446
            $commits = $this->request('https://api.github.com/repos/'.$owner.DIRECTORY_SEPARATOR.
447
                $repo.'/pulls/'.$pull->number.'/commits');
448
            foreach ($commits as $commit) {
449
                $c = Commit::where('sha', '=', $commit->sha)->first();
450
                $pull->commit()->sync([$c->id], false);
451
            }
452
        }
453
    }
454
455
    public function getStatsCommitActivity($owner, $repo)
456
    {
457
        ///repos/:owner/:repo/stats/contributors
458
        $stats = $this->request('https://api.github.com/repos/'.$owner.DIRECTORY_SEPARATOR.
459
            $repo.'/stats/commit_activity');
460
        $arr = [];
461
        foreach ($stats as $stat) {
462
            $arr[] = $stat->total;
463
        }
464
465
        return $arr;
466
    }
467
}
468