Completed
Push — master ( 14ad8e...ded44c )
by Renato
10s
created

Github   B

Complexity

Total Complexity 43

Size/Duplication

Total Lines 251
Duplicated Lines 0 %

Coupling/Cohesion

Components 0
Dependencies 9

Importance

Changes 4
Bugs 0 Features 1
Metric Value
wmc 43
c 4
b 0
f 1
lcom 0
cbo 9
dl 0
loc 251
rs 8.3157

12 Methods

Rating   Name   Duplication   Size   Complexity  
A tplRepository() 0 22 2
A tplIssue() 0 21 2
A readRepositories() 0 10 1
A createOrUpdateRepository() 0 22 3
B organization() 0 45 4
C tplUser() 0 17 11
B readCollaborators() 0 28 4
A createBranches() 0 18 4
B readIssues() 0 22 6
A createOrUpdateIssue() 0 14 2
A createOrUpdateIssueComment() 0 14 3
A deleteIssueComment() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like Github often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Github, and based on these observations, apply Extract Interface, too.

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\User;
9
use GitScrum\Models\Issue;
10
use GitScrum\Models\Organization;
11
use GitScrum\Models\ProductBacklog;
12
use Carbon\Carbon;
13
use GitScrum\Contracts\ProviderInterface;
14
15
class Github implements ProviderInterface
16
{
17
    public function tplUser($obj)
18
    {
19
        return [
20
            'provider_id' => $obj->id,
21
            'provider' => 'github',
22
            'username' => isset($obj->login) ? $obj->login : $obj->nickname,
23
            'name' => isset($obj->name) ? $obj->name : null,
24
            'token' => isset($obj->token) ? $obj->token : null,
25
            'avatar' => isset($obj->user['avatar_url']) ? $obj->user['avatar_url'] : $obj->avatar_url,
26
            'html_url' => isset($obj->user['html_url']) ? $obj->user['html_url'] : $obj->html_url,
27
            'bio' => isset($obj->user['bio']) ? $obj->user['bio'] : null,
28
            'since' => isset($obj->user['created_at']) ? Carbon::parse($obj->user['created_at'])->toDateTimeString() : Carbon::now(),
29
            'location' => isset($obj->user['location']) ? $obj->user['location'] : null,
30
            'blog' => isset($obj->user['blog']) ? $obj->user['blog'] : null,
31
            'email' => isset($obj->email) ? $obj->email : null,
32
        ];
33
    }
34
35
    public function tplRepository($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...
36
    {
37
        return (object) [
38
            'provider_id' => $repo->id,
39
            'organization_id' => $this->organization($repo->owner->login),
40
            'organization_title' => $repo->owner->login,
41
            'slug' => $slug ? $slug : Helper::slug($repo->name),
42
            'title' => $repo->name,
43
            'fullname' => $repo->full_name,
44
            'is_private' => $repo->private,
45
            'html_url' => $repo->html_url,
46
            'description' => $repo->description,
47
            'fork' => $repo->fork,
48
            'url' => $repo->url,
49
            'since' => Carbon::parse($repo->created_at)->toDateTimeString(),
50
            'pushed_at' => Carbon::parse($repo->pushed_at)->toDateTimeString(),
51
            'ssh_url' => $repo->ssh_url,
52
            'clone_url' => $repo->clone_url,
53
            'homepage' => $repo->homepage,
54
            'default_branch' => $repo->default_branch,
55
        ];
56
    }
57
58
    public function tplIssue($obj, $productBracklogId)
59
    {
60
        $user = User::where('username', @$obj->user->login)
61
            ->where('provider', 'github')->first();
62
63
        return [
64
            'provider_id' => $obj->id,
65
            'user_id' => isset($user->id) ? $user->id : Auth::user()->id,
66
            'product_backlog_id' => $productBracklogId,
67
            'effort' => 0,
68
            'config_issue_effort_id' => 1,
69
            'issue_type_id' => 1,
70
            'number' => $obj->number,
71
            'title' => $obj->title,
72
            'description' => $obj->body,
73
            'state' => $obj->state,
74
            'html_url' => $obj->html_url,
75
            'created_at' => $obj->created_at,
76
            'updated_at' => $obj->updated_at,
77
        ];
78
    }
79
80
    public function readRepositories()
81
    {
82
        $repos = collect(Helper::request('https://api.github.com/user/repos'));
83
84
        $response = $repos->map(function ($repo) {
85
            return $this->tplRepository($repo);
86
        });
87
88
        return $response;
89
    }
90
91
    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...
92
    {
93
        $params = [
94
            'name' => str_slug($obj->title, '-'),
95
            'description' => $obj->description,
96
        ];
97
98
        if (is_null($oldTitle)) {
99
            $endpoint = 'https://api.github.com/orgs/'.$owner.'/repos';
100
101
            if (Auth::user()->username == $owner) {
102
                $endpoint = 'https://api.github.com/user/repos';
103
            }
104
105
            $response = Helper::request($endpoint, true, 'POST', $params);
106
        } else {
107
            $oldTitle = str_slug($oldTitle, '-');
108
            $response = Helper::request('https://api.github.com/repos/'.$owner.DIRECTORY_SEPARATOR.$oldTitle, true, 'POST', $params);
109
        }
110
111
        return (object) $response;
112
    }
113
114
    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...
115
    {
116
        $organization = Organization::where('username', $login)
117
            ->where('provider', 'github')->first();
118
119
        if (!isset($organization)) {
120
            $orgData = Helper::request('https://api.github.com/orgs/'.$login);
121
122
            if (!isset($orgData->id)) {
123
                $orgData = Helper::request('https://api.github.com/users/'.$login);
124
            }
125
126
            $data = [
127
                'provider_id' => @$orgData->id,
128
                'username' => @$orgData->login,
129
                'url' => @$orgData->url,
130
                'repos_url' => @$orgData->repos_url,
131
                'events_url' => @$orgData->events_url,
132
                'hooks_url' => @$orgData->hooks_url,
133
                'issues_url' => @$orgData->issues_url,
134
                'members_url' => @$orgData->members_url,
135
                'public_members_url' => @$orgData->public_members_url,
136
                'avatar_url' => @$orgData->avatar_url,
137
                'description' => @$orgData->description,
138
                'title' => @$orgData->name,
139
                'blog' => @$orgData->blog,
140
                'location' => @$orgData->location,
141
                'email' => @$orgData->email,
142
                'public_repos' => @$orgData->public_repos,
143
                'html_url' => @$orgData->html_url,
144
                'total_private_repos' => @$orgData->total_private_repos,
145
                'since' => @Carbon::parse($orgData->created_at)->toDateTimeString(),
146
                'disk_usage' => @$orgData->disk_usage,
147
            ];
148
149
            try {
150
                $organization = Organization::create($data);
151
            } 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...
152
            }
153
154
            $organization->users()->sync([Auth::id()]);
155
        }
156
157
        return $organization->id;
158
    }
159
160
    public function readCollaborators($owner, $repo, $providerId = null)
161
    {
162
        $ids = collect();
163
        $collaborators = Helper::request('https://api.github.com/repos/'.$owner.'/'.$repo.'/collaborators');
164
        foreach ($collaborators as $collaborator) {
165
            if (isset($collaborator->id)) {
166
167
                $data = $this->tplUser($collaborator);
168
169
                try {
170
                    $user = User::create($data);
171
                } catch (\Exception $e) {
172
                    $user = User::where('username', $collaborator->login)
173
                        ->where('provider', 'github')->first();
174
                }
175
176
                $ids->push($user->id);
177
            }
178
        }
179
180
        $organization = Organization::where('username', $owner)
181
            ->where('provider', 'github')->first()->users();
182
183
        $ids->diff($organization->pluck('user_id')->toArray())->map(function($id) use ($organization){
184
            $organization->attach($id);
185
        });
186
187
    }
188
189
    public function createBranches($owner, $product_backlog_id, $repo, $providerId = null)
190
    {
191
        $y = 0;
192
        for ($i = 1; $i > $y; ++$i) {
193
            $branches = Helper::request('https://api.github.com/repos/'.$owner.DIRECTORY_SEPARATOR.$repo.'/branches?page='.$i);
194
            foreach ($branches as $branch) {
195
                $data = [
196
                    'product_backlog_id' => $product_backlog_id,
197
                    'title' => $branch->name,
198
                    'sha' => $branch->commit->sha,
199
                ];
200
                Branch::create($data);
201
            }
202
            if (count($branches) < 30) {
203
                $y = $i + 2;
204
            }
205
        }
206
    }
207
208
    public function readIssues()
209
    {
210
        $repos = ProductBacklog::all();
211
212
        foreach ($repos as $repo) {
213
            $issues = Helper::request('https://api.github.com/repos/'.$repo->organization->username.
214
                DIRECTORY_SEPARATOR.$repo->title.'/issues?state=all');
215
216
            $issues = is_array($issues) ? $issues : [$issues];
217
218
            foreach ($issues as $issue) {
219
                try {
220
                    $data = $this->tplIssue($issue, $repo->id);
221
                } catch (\Exception $e) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
222
                }
223
224
                if (!Issue::where('provider_id', $issue->id)->where('provider', 'github')->first()) {
225
                    Issue::create($data)->users()->sync([$data['user_id']]);
226
                }
227
            }
228
        }
229
    }
230
231
    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...
232
    {
233
        $params = [
234
            'title' => $obj->title,
235
            'body' => $obj->description,
236
        ];
237
238
        $response = Helper::request('https://api.github.com/repos/'.
239
            $obj->productBacklog->organization->username.DIRECTORY_SEPARATOR.
240
            $obj->productBacklog->title.'/issues'.(isset($obj->number) ? DIRECTORY_SEPARATOR.$obj->number : ''),
241
            true, 'POST', $params);
242
243
        return (object) $response;
244
    }
245
246
    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...
247
    {
248
        $params = [
249
            'body' => $obj->comment,
250
        ];
251
252
        $response = Helper::request('https://api.github.com/repos/'.
253
            $obj->issue->productBacklog->organization->username.DIRECTORY_SEPARATOR.
254
            $obj->issue->productBacklog->title.'/issues'.(isset($obj->provider_id) ? '' : DIRECTORY_SEPARATOR.$obj->issue->number).'/comments'.
255
            (isset($obj->provider_id) ? DIRECTORY_SEPARATOR.$obj->provider_id : ''),
256
            true, $verb, $params);
257
258
        return (object) $response;
259
    }
260
261
    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...
262
    {
263
        return $this->createOrUpdateIssueComment($obj, 'DELETE');
264
    }
265
}
266