Completed
Push — master ( 39dbfd...23dd4b )
by Renato
02:42
created

Github::getStatsCommitActivity()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 2
1
<?php
2
3
namespace GitScrum\Classes;
4
5
use Auth;
6
use GitScrum\Repository;
7
use GitScrum\Branch;
8
use GitScrum\Commit;
9
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...
10
use GitScrum\Models\User;
11
use GitScrum\Models\Organization;
12
use GitScrum\Models\ProductBacklog;
13
use Carbon\Carbon;
14
15
class Github
16
{
17
18
    public function getRepositories()
19
    {
20
        $repos = $this->request('https://api.github.com/user/repos');
21
22
        foreach ($repos as $repo) {
23
            $data[] = (object) [
0 ignored issues
show
Coding Style Comprehensibility introduced by
$data was never initialized. Although not strictly required by PHP, it is generally a good practice to add $data = 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...
24
                'github_id' => $repo->id,
25
                'organization_id' => $this->organization($repo->owner->login),
26
                'organization_title' => $repo->owner->login,
27
                'slug' => Helper::slug($repo->name),
28
                'title' => $repo->name,
29
                'fullname' => $repo->full_name,
30
                'is_private' => $repo->private,
31
                'html_url' => $repo->html_url,
32
                'description' => $repo->description,
33
                'fork' => $repo->fork,
34
                'url' => $repo->url,
35
                'since' => Carbon::parse($repo->created_at)->toDateTimeString(),
36
                'pushed_at' => Carbon::parse($repo->pushed_at)->toDateTimeString(),
37
                'ssh_url' => $repo->ssh_url,
38
                'clone_url' => $repo->clone_url,
39
                'homepage' => $repo->homepage,
40
                'default_branch' => $repo->default_branch,
41
            ];
42
        }
43
44
        return collect($data);
0 ignored issues
show
Bug introduced by
The variable $data 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...
45
    }
46
47
    public function repositories()
48
    {
49
        $repos = $this->request('https://api.github.com/user/repos');
50
51
        foreach ($repos as $repo) {
52
            $data = [
53
                'github_id' => $repo->id,
54
                'organization_id' => $this->organization($repo->owner->login),
55
                'slug' => Helper::slug($repo->name),
56
                'title' => $repo->name,
57
                'fullname' => $repo->full_name,
58
                'is_private' => $repo->private,
59
                'html_url' => $repo->html_url,
60
                'description' => $repo->description,
61
                'fork' => $repo->fork,
62
                'url' => $repo->url,
63
                'since' => Carbon::parse($repo->created_at)->toDateTimeString(),
64
                'pushed_at' => Carbon::parse($repo->pushed_at)->toDateTimeString(),
65
                'ssh_url' => $repo->ssh_url,
66
                'clone_url' => $repo->clone_url,
67
                'homepage' => $repo->homepage,
68
                'default_branch' => $repo->default_branch,
69
            ];
70
71
            try {
72
                ProductBacklog::create($data);
73
            } catch (\Illuminate\Database\QueryException $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
74
            }
75
        }
76
    }
77
78
    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...
79
    {
80
        $orgData = $this->request('https://api.github.com/orgs/'.$login);
81
82
        if (!isset($orgData->id)) {
83
            $orgData = $this->request('https://api.github.com/users/'.$login);
84
        }
85
86
        $data = [
87
            'github_id' => @$orgData->id,
88
            'username' => @$orgData->login,
89
            'url' => @$orgData->url,
90
            'repos_url' => @$orgData->repos_url,
91
            'events_url' => @$orgData->events_url,
92
            'hooks_url' => @$orgData->hooks_url,
93
            'issues_url' => @$orgData->issues_url,
94
            'members_url' => @$orgData->members_url,
95
            'public_members_url' => @$orgData->public_members_url,
96
            'avatar_url' => @$orgData->avatar_url,
97
            'description' => @$orgData->description,
98
            'title' => @$orgData->name,
99
            'blog' => @$orgData->blog,
100
            'location' => @$orgData->location,
101
            'email' => @$orgData->email,
102
            'public_repos' => @$orgData->public_repos,
103
            'html_url' => @$orgData->html_url,
104
            'total_private_repos' => @$orgData->total_private_repos,
105
            'since' => @Carbon::parse($orgData->created_at)->toDateTimeString(),
106
            'disk_usage' => @$orgData->disk_usage,
107
        ];
108
109
        try {
110
            $organization = Organization::create($data);
111
        } catch (\Illuminate\Database\QueryException $e) {
112
            $organization = Organization::where('username', $orgData->login)->first();
113
        }
114
115
        if (!isset(Auth::user()->organizations()->where(
116
            'organization_id',
117
            $organization->id
118
        )->first()->id)) {
119
            Auth::user()->organizations()->attach($organization->id);
120
        }
121
122
        $this->members($orgData->login);
123
124
        return $organization->id;
125
    }
126
127
    public function members($org)
128
    {
129
        $members = $this->request('https://api.github.com/orgs/'.$org.'/members');
130
        $organization = Organization::where('username', $org)->first()->users();
131
132
        foreach ($members as $member) {
133
            if (isset($member->id)) {
134
                $data = [
135
                    'github_id' => $member->id,
136
                    'username' => $member->login,
137
                    'name' => $member->login,
138
                    'avatar' => $member->avatar_url,
139
                    'html_url' => $member->html_url,
140
                    'email' => null,
141
                    'remember_token' => null,
142
                    'bio' => null,
143
                    'location' => null,
144
                    'blog' => null,
145
                    'since' => null,
146
                    'token' => null,
147
                    'position_held' => null,
148
                ];
149
150
                try {
151
                    $user = User::create($data);
152
                } catch (\Exception $e) {
153
                    $user = User::where('username', $member->login)->first();
154
                }
155
156
                if (!isset($organization->where('user_id', Auth::user()->id)->first()->id)) {
157
                    $organization->attach($user->id);
158
                }
159
            }
160
        }
161
    }
162
163
    private function request($url, $auth = true)
164
    {
165
        $user = Auth::user();
166
        $ch = curl_init();
167
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:7.0.1) Gecko/20100101 Firefox/7.0.1');
168
        curl_setopt($ch, CURLOPT_URL, $url);
169
        curl_setopt($ch, CURLOPT_TIMEOUT, 30);
170
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
171
        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
172
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
173
        if ($auth) {
174
            curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
175
            curl_setopt($ch, CURLOPT_USERPWD, $user->username.':'.$user->token);
176
        }
177
        $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...
178
        $result = curl_exec($ch);
179
        curl_close($ch);
180
181
        return json_decode($result);
182
    }
183
184
    /*
185
    public function organizations(){
186
        $this->request('https://api.github.com/user/orgs');
187
    }
188
189
    public function repositories($org){
190
        ///orgs/:org/repos
191
        return $this->request('https://api.github.com/orgs/'.$org.'/repos');
192
    }
193
    */
194
195
    public function setIssues($owner, $repo)
196
    {
197
        $issues = $this->request('https://api.github.com/repos/'.$owner.'/'.$repo.'/issues?state=all');
198
        $repository = Repository::where('name', $repo)->first();
199
        $IssueRepository = new IssueRepository();
200
        foreach ($issues as $issue) {
201
            $data = [
202
                'github_id' => $issue->id,
203
                'product_backlog_id' => $repository->id,
204
                'number' => $issue->number,
205
                'title' => $issue->title,
206
                'body' => $issue->body,
207
                'state' => $issue->state,
208
                'html_url' => $issue->html_url,
209
                'date' => $issue->created_at,
210
            ];
211
            $issueId = $IssueRepository->add($data)->id;
212
            foreach ($issue->assignees as $assign) {
213
                User::where('github_id', $assign->id)->first()->issues()->sync([$issueId], false);
214
            }
215
        }
216
    }
217
218
    public function issues()
219
    {
220
        return $this->request('https://api.github.com/repos/Doinn/Dracarys/issues/317');
221
    }
222
223
    public function setBranches($owner, $repo)
224
    {
225
        ///repos/:owner/:repo/branches
226
        $y = 0;
227
        for ($i = 1; $i > $y; ++$i) {
228
            $branches = $this->request('https://api.github.com/repos/'.$owner.'/'.$repo.'/branches?page='.$i);
229
            $repository = Repository::where('name', $repo)->first();
230
            $BranchRepository = new BranchRepository();
231
            foreach ($branches as $branch) {
232
                $data = [
233
                    'product_backlog_id' => $repository->id,
234
                    'name' => $branch->name,
235
                    'sha' => $branch->commit->sha,
236
                ];
237
                $BranchRepository->add($data);
238
                $this->setCommits($owner, $repo, $branch->name);
239
                $this->setPullRequest($owner, $repo);
240
            }
241
            if (count($branches) < 30) {
242
                $y = $i + 2;
243
            }
244
        }
245
    }
246
247
    public function setCommits($owner, $repo, $branch, $since = null)
248
    {
249
        ////repos/:owner/:repo/commits?sha=branchname
250
        $y = 0;
251
        for ($i = 1; $i > $y; ++$i) {
252
            $commits = $this->request('https://api.github.com/repos/'.$owner.'/'.$repo.'/commits?page='.$i.'&sha='.$branch.(is_null($since) ? '' : '&since='.$since));
253
            $branch = Branch::join('product_backlogs', 'branches.product_backlog_id', '=', 'repositories.id')
254
                            ->where('branches.name', $branch)
255
                            ->where('product_backlogs.name', $repo)
256
                            ->select('branches.id AS branch_id', 'repositories.id AS product_backlog_id')->first();
257
            $CommitRepository = new CommitRepository();
258
            foreach ($commits as $commit) {
259
                try {
260
                    $user = User::where('github_id', $commit->author->id)->first();
261
                    $userId = $user->id;
262
                } catch (\Exception $e) {
263
                    $userId = 0;
264
                }
265
                try {
266
                    if (isset($commit->sha)) {
267
                        $data = [
268
                            'product_backlog_id' => $branch->product_backlog_id,
269
                            'branch_id' => $branch->branch_id,
270
                            'user_id' => $userId,
271
                            'sha' => $commit->sha,
272
                            'url' => $commit->url,
273
                            'message' => $commit->commit->message,
274
                            'html_url' => $commit->html_url,
275
                            'date' => $commit->commit->author->date,
276
                            'tree_sha' => $commit->commit->tree->sha,
277
                            'tree_url' => $commit->commit->tree->url,
278
                        ];
279
                        $commitData = $CommitRepository->add($data);
280
                        $this->setCommitFiles($owner, $repo, $commitData->sha, $commitData);
281
                    }
282
                } catch (\Exception $e) {
283
                    dd($data, $commit);
284
                }
285
            }
286
            if (count($commits) < 30) {
287
                $y = $i + 2;
288
            }
289
        }
290
    }
291
292
    public function setCommitFiles($owner, $repo, $sha, $objCommit)
293
    {
294
        // /repos/:owner/:repo/commits/:sha
295
        $commits = $this->request('https://api.github.com/repos/'.$owner.'/'.$repo.'/commits/'.$sha);
296
        $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...
297
        $CommitRepository = new CommitRepository();
298
        foreach ($commits->files as $commit) {
299
            try {
300
                $contents = $this->request($commit->contents_url);
301
                $fileRaw = file_get_contents($contents->download_url);
302
                $data = [
303
                    'commit_id' => $objCommit->id,
304
                    'sha' => $commit->sha,
305
                    'filename' => $commit->filename,
306
                    'status' => $commit->status,
307
                    'additions' => $commit->additions,
308
                    'deletions' => $commit->deletions,
309
                    'changes' => $commit->changes,
310
                    'raw_url' => $commit->raw_url,
311
                    'raw' => $fileRaw,
312
                    'patch' => (isset($commit->patch) ? $commit->patch : ''),
313
                ];
314
                $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...
315
                //$Phpcs->init($fileRaw, $commitData->id);
316
            } catch (\Exception $e) {
317
                echo 'erro files ... ';
318
            }
319
        }
320
    }
321
322
    public function getCommit($owner, $repo, $sha)
323
    {
324
        // /repos/:owner/:repo/commits/:sha
325
        $commits = $this->request('https://api.github.com/repos/'.$owner.'/'.$repo.'/commits/'.$sha);
326
        dd($commits);
327
        /*
328
        foreach ($commits as $commit) {
329
            $data = [
330
                'commit_id'=>$objCommit->id,
331
                'sha'=>,
332
                'filename'=>,
333
                'status'=>,
334
                'additions'=>,
335
                'deletetions'=>,
336
                'changes'=>,
337
                'raw_url'=>,
338
                'patch'=>
339
            ];
340
        }*/
341
    }
342
343
    public function setPullRequest($owner, $repo)
344
    {
345
        ///repos/:owner/:repo/pulls
346
        $pulls = $this->request('https://api.github.com/repos/'.$owner.'/'.$repo.'/pulls');
347
        $repository = Repository::where('name', $repo)->first();
348
        $PullRequestRepository = new PullRequestRepository();
349
        foreach ($pulls as $pull) {
350
            $branch = Branch::where('name', $pull->head->ref)->first();
351
            try {
352
                $user = User::where('github_id', $pull->user->id)->first();
353
                $userId = $user->id;
354
            } catch (\Exception $e) {
355
                $userId = 0;
356
            }
357
358
            try {
359
                $headBranchId = $branch->id;
360
            } 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...
361
                $headBranchId = 0;
362
            }
363
364
            try {
365
                $branch = Branch::where('name', $pull->base->ref)->first();
366
                $baseBranchId = $branch->id;
367
            } catch (\Exception $e) {
368
                $baseBranchId = 0;
369
            }
370
371
            $data = [
372
                'github_id' => $pull->id,
373
                'number' => $pull->number,
374
                'user_id' => $userId,
375
                'product_backlog_id' => $repository->id,
376
                'url' => $pull->url,
377
                'html_url' => $pull->html_url,
378
                'issue_url' => $pull->issue_url,
379
                'commits_url' => $pull->commits_url,
380
                'state' => $pull->state,
381
                'title' => $pull->title,
382
                'body' => $pull->body,
383
                'github_created_at' => $pull->created_at,
384
                'github_updated_at' => $pull->updated_at,
385
                'head_branch_id' => $headBranchId,
386
                'base_branch_id' => $baseBranchId,
387
            ];
388
389
            $pull = $PullRequestRepository->add($data);
390
391
            $commits = $this->request('https://api.github.com/repos/'.$owner.'/'.$repo.'/pulls/'.$pull->number.'/commits');
392
            //dd($commits);
393
            foreach ($commits as $commit) {
394
                $c = Commit::where('sha', '=', $commit->sha)->first();
395
                $pull->commit()->sync([$c->id], false);
396
            }
397
        }
398
    }
399
400
    public function getStatsCommitActivity($owner, $repo)
401
    {
402
        ///repos/:owner/:repo/stats/contributors
403
        $stats = $this->request('https://api.github.com/repos/'.$owner.'/'.$repo.'/stats/commit_activity');
404
        $arr = [];
405
        foreach ($stats as $stat) {
406
            $arr[] = $stat->total;
407
        }
408
409
        return $arr;
410
    }
411
}
412