Completed
Push — master ( d34b48...29b4e2 )
by Дмитрий
15:04 queued 13:34
created

GitHub::getPrimaryEmail()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 13
ccs 0
cts 9
cp 0
rs 9.2
cc 4
eloc 7
nc 3
nop 1
crap 20
1
<?php
2
/**
3
 * SocialConnect project
4
 * @author: Patsura Dmitry https://github.com/ovr <[email protected]>
5
 */
6
7
namespace SocialConnect\OAuth2\Provider;
8
9
use SocialConnect\Provider\AccessTokenInterface;
10
use SocialConnect\Provider\Exception\InvalidResponse;
11
use SocialConnect\Common\Entity\User;
12
use SocialConnect\Common\Hydrator\ObjectMap;
13
14
class GitHub extends \SocialConnect\OAuth2\AbstractProvider
15
{
16
    /**
17
     * @var array
18
     */
19
    protected $options = [
20
        /**
21
         * GitHub store only unverified and public email inside User
22
         * It's not possible to fetch user with email in GraphQL (new api)
23
         * For now, there is only one way, additional request for it by user/email API entrypoint
24
         *
25
         * It's disabled by default in SocialConnect 1.x, but you can enable it from configuration :)
26
         */
27
        'fetch_emails' => false
28
    ];
29
30 3
    public function getBaseUri()
31
    {
32 3
        return 'https://api.github.com/';
33
    }
34
35 2
    public function getAuthorizeUri()
36
    {
37 2
        return 'https://github.com/login/oauth/authorize';
38
    }
39
40 2
    public function getRequestTokenUri()
41
    {
42 2
        return 'https://github.com/login/oauth/access_token';
43
    }
44
45 3
    public function getName()
46
    {
47 3
        return 'github';
48
    }
49
50
    /**
51
     * {@inheritdoc}
52
     */
53 2
    public function getIdentity(AccessTokenInterface $accessToken)
54
    {
55 2
        $response = $this->httpClient->request(
56 2
            $this->getBaseUri() . 'user',
57
            [
58 2
                'access_token' => $accessToken->getToken()
59 2
            ]
60 2
        );
61
62 2
        if (!$response->isSuccess()) {
63 1
            throw new InvalidResponse(
64 1
                'API response with error code',
65
                $response
66 1
            );
67
        }
68
69 1
        $result = $response->json();
70 1
        if (!$result) {
71 1
            throw new InvalidResponse(
72 1
                'API response is not a valid JSON object',
73
                $response
74 1
            );
75
        }
76
77
        $hydrator = new ObjectMap(
78
            [
79
                'id' => 'id',
80
                'login' => 'username',
81
                'email' => 'email',
82
            ]
83
        );
84
85
        /** @var User $user */
86
        $user = $hydrator->hydrate(new User(), $result);
87
88
        if ($this->getBoolOption('fetch_emails', false)) {
89
            $primaryEmail = $this->getPrimaryEmail($accessToken);
90
            if ($primaryEmail) {
91
                $user->email = $primaryEmail->email;
92
                $user->emailVerified = $primaryEmail->verified;
93
            }
94
        }
95
96
        return $user;
97
    }
98
99
100
    /**
101
     * @param AccessTokenInterface $accessToken
102
     * @return object
103
     * @throws InvalidResponse
104
     */
105
    public function getPrimaryEmail(AccessTokenInterface $accessToken)
106
    {
107
        $emails = $this->getEmails($accessToken);
108
        if ($emails) {
0 ignored issues
show
Bug Best Practice introduced by Dmitry Patsura
The expression $emails of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
109
            foreach ($emails as $email) {
110
                if ($email->primary) {
111
                    return $email;
112
                }
113
            }
114
        }
115
116
        return null;
117
    }
118
119
    /**
120
     * @param AccessTokenInterface $accessToken
121
     * @return array
122
     * @throws InvalidResponse
123
     */
124
    public function getEmails(AccessTokenInterface $accessToken)
125
    {
126
        $response = $this->httpClient->request(
127
            $this->getBaseUri() . 'user/emails',
128
            [
129
                'access_token' => $accessToken->getToken()
130
            ]
131
        );
132
133
        if (!$response->isSuccess()) {
134
            throw new InvalidResponse(
135
                'API response with error code',
136
                $response
137
            );
138
        }
139
140
        $result = $response->json();
141
        if (!$result) {
142
            throw new InvalidResponse(
143
                'API response is not a valid JSON object',
144
                $response
145
            );
146
        }
147
148
        return $result;
149
    }
150
}
151