Passed
Push — master ( 6085c2...2876b8 )
by George
01:34
created

Vkontakte::checkResponse()   B

Complexity

Conditions 9
Paths 64

Size

Total Lines 27
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 16
dl 0
loc 27
rs 8.0555
c 0
b 0
f 0
cc 9
nc 64
nop 2
1
<?php
2
3
namespace J4k\OAuth2\Client\Provider;
4
5
use League\OAuth2\Client\Provider\AbstractProvider;
6
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
7
use League\OAuth2\Client\Token\AccessToken;
8
use Psr\Http\Message\ResponseInterface;
9
10
class Vkontakte extends AbstractProvider
11
{
12
    protected $baseOAuthUri = 'https://oauth.vk.com';
13
    protected $baseUri = 'https://api.vk.com/method';
14
    protected $version = '5.7';
15
    protected $language = null;
16
17
    /**
18
     * @type array
19
     * @see https://vk.com/dev/permissions
20
     */
21
    public $scopes = [
22
        'email',
23
        'friends',
24
        'offline',
25
        //'photos',
26
        //'wall',
27
        //'ads',
28
        //'audio',
29
        //'docs',
30
        //'groups',
31
        //'market',
32
        //'messages',
33
        //'nohttps',
34
        //'notes',
35
        //'notifications',
36
        //'notify',
37
        //'pages',
38
        //'stats',
39
        //'status',
40
        //'video',
41
    ];
42
    /**
43
     * @type array
44
     * @see https://new.vk.com/dev/fields
45
     */
46
    public $userFields = [
47
        'bdate',
48
        'city',
49
        'country',
50
        'domain',
51
        'first_name',
52
        'friend_status',
53
        'has_photo',
54
        'home_town',
55
        'id',
56
        'is_friend',
57
        'last_name',
58
        'maiden_name',
59
        'nickname',
60
        'photo_max',
61
        'photo_max_orig',
62
        'screen_name',
63
        'sex',
64
        //'about',
65
        //'activities',
66
        //'blacklisted',
67
        //'blacklisted_by_me',
68
        //'books',
69
        //'can_post',
70
        //'can_see_all_posts',
71
        //'can_see_audio',
72
        //'can_send_friend_request',
73
        //'can_write_private_message',
74
        //'career',
75
        //'common_count',
76
        //'connections',
77
        //'contacts',
78
        //'crop_photo',
79
        //'counters',
80
        //'deactivated',
81
        //'education',
82
        //'exports',
83
        //'followers_count',
84
        //'games',
85
        //'has_mobile',
86
        //'hidden',
87
        //'interests',
88
        //'is_favorite',
89
        //'is_hidden_from_feed',
90
        //'last_seen',
91
        //'military',
92
        //'movies',
93
        //'occupation',
94
        //'online',
95
        //'personal',
96
        //'photo_100',
97
        //'photo_200',
98
        //'photo_200_orig',
99
        //'photo_400_orig',
100
        //'photo_50',
101
        //'photo_id',
102
        //'quotes',
103
        //'relation',
104
        //'relatives',
105
        //'schools',
106
        //'site',
107
        //'status',
108
        //'timezone',
109
        //'tv',
110
        //'universities',
111
        //'verified',
112
        //'wall_comments',
113
    ];
114
115
    /**
116
     * @param $language
117
     * @return $this
118
     */
119
    public function setLanguage($language)
120
    {
121
        $this->language = (string)$language;
122
123
        return $this;
124
    }
125
126
    /**
127
     * @return string
128
     */
129
    public function getBaseAuthorizationUrl()
130
    {
131
        return "$this->baseOAuthUri/authorize";
132
    }
133
134
    /**
135
     * @return string
136
     */
137
    public function getBaseAccessTokenUrl(array $params)
138
    {
139
        return "$this->baseOAuthUri/access_token";
140
    }
141
142
    /**
143
     * @param AccessToken $token
144
     * @return string
145
     */
146
    public function getResourceOwnerDetailsUrl(AccessToken $token)
147
    {
148
        $params = [
149
            'fields' => $this->userFields,
150
            'access_token' => $token->getToken(),
151
            'v' => $this->version,
152
            'lang' => $this->language
153
        ];
154
        $query = $this->buildQueryString($params);
155
        $url = "$this->baseUri/users.get?$query";
156
157
        return $url;
158
    }
159
160
    /**
161
     * @return array
162
     */
163
    protected function getDefaultScopes()
164
    {
165
        return $this->scopes;
166
    }
167
168
    /**
169
     * @param ResponseInterface $response
170
     * @param array|string $data
171
     * @throws IdentityProviderException
172
     */
173
    protected function checkResponse(ResponseInterface $response, $data)
174
    {
175
        // Metadata info
176
        $contentTypeRaw = $response->getHeader('Content-Type');
177
        $contentTypeArray = explode(';', reset($contentTypeRaw));
178
        $contentType = reset($contentTypeArray);
179
        // Response info
180
        $responseCode = $response->getStatusCode();
181
        $responseMessage = $response->getReasonPhrase();
182
        // Data info
183
        $error = !empty($data['error']) ? $data['error'] : null;
184
        $errorCode = !empty($error['error_code']) ? $error['error_code'] : $responseCode;
185
        $errorDescription = !empty($data['error_description']) ? $data['error_description'] : null;
186
        $errorMessage = !empty($error['error_msg']) ? $error['error_msg'] : $errorDescription;
187
        $message = $errorMessage ?: $responseMessage;
188
189
        // Request/meta validation
190
        if (399 < $responseCode) {
191
            throw new IdentityProviderException($message, $responseCode, $data);
192
        }
193
194
        // Content validation
195
        if ('application/json' != $contentType) {
196
            throw new IdentityProviderException($message, $responseCode, $data);
197
        }
198
        if ($error) {
199
            throw new IdentityProviderException($errorMessage, $errorCode, $data);
200
        }
201
    }
202
203
    /**
204
     * @param array $response
205
     * @param AccessToken $token
206
     * @return User|\League\OAuth2\Client\Provider\ResourceOwnerInterface
207
     */
208
    protected function createResourceOwner(array $response, AccessToken $token)
209
    {
210
        $response = reset($response['response']);
211
        $additional = $token->getValues();
212
        if (!empty($additional['email'])) {
213
            $response['email'] = $additional['email'];
214
        }
215
        if (!empty($response['uid']) && 4 === floor($this->version)) {
0 ignored issues
show
Bug introduced by
$this->version of type string is incompatible with the type double expected by parameter $value of floor(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

215
        if (!empty($response['uid']) && 4 === floor(/** @scrutinizer ignore-type */ $this->version)) {
Loading history...
216
            $response['id'] = $response['uid'];
217
        }
218
        if (!empty($additional['user_id'])) {
219
            $response['id'] = $additional['user_id'];
220
        }
221
        // @TODO Investigate and fix this code smell
222
223
        return new User($response, $response['id']);
0 ignored issues
show
Unused Code introduced by
The call to J4k\OAuth2\Client\Provider\User::__construct() has too many arguments starting with $response['id']. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

223
        return /** @scrutinizer ignore-call */ new User($response, $response['id']);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
224
    }
225
226
    /**
227
     * @see https://vk.com/dev/users.get
228
     *
229
     * @param integer[] $ids
230
     * @param AccessToken|null $token Current user if empty
231
     * @param array $params
232
     *
233
     * @return User[]
234
     */
235
    public function usersGet(array $ids = [], AccessToken $token = null, array $params = [])
236
    {
237
        if (empty($ids) && !$token) {
238
            throw new \InvalidArgumentException('Some of parameters usersIds OR access_token are required');
239
        }
240
241
        $default = [
242
            'user_ids' => implode(',', $ids),
243
            'fields' => $this->userFields,
244
            'access_token' => $token ? $token->getToken() : null,
245
            'v' => $this->version,
246
            'lang' => $this->language
247
        ];
248
        $params = array_merge($default, $params);
249
        $query = $this->buildQueryString($params);
250
        $url = "$this->baseUri/users.get?$query";
251
252
        $response = $this->getResponse($this->createRequest(static::METHOD_GET, $url, $token, []))['response'];
253
        $users = !empty($response['items']) ? $response['items'] : $response;
254
        $array2user = function ($userData) {
255
            return new User($userData);
256
        };
257
258
        return array_map($array2user, $users);
259
    }
260
261
    /**
262
     * @see https://vk.com/dev/friends.get
263
     *
264
     * @param integer $userId
265
     * @param AccessToken|null $token
266
     * @param array $params
267
     *
268
     * @return User[]
269
     */
270
    public function friendsGet($userId, AccessToken $token = null, array $params = [])
271
    {
272
        $default = [
273
            'user_id' => $userId,
274
            'fields' => $this->userFields,
275
            'access_token' => $token ? $token->getToken() : null,
276
            'v' => $this->version,
277
            'lang' => $this->language
278
        ];
279
        $params = array_merge($default, $params);
280
        $query = $this->buildQueryString($params);
281
        $url = "$this->baseUri/friends.get?$query";
282
283
        $response = $this->getResponse($this->createRequest(static::METHOD_GET, $url, $token, []))['response'];
284
        $friends = !empty($response['items']) ? $response['items'] : $response;
285
        $array2friend = function ($friendData) {
286
            if (is_numeric($friendData)) {
287
                $friendData = ['id' => $friendData];
288
            }
289
290
            return new User($friendData);
291
        };
292
293
        return array_map($array2friend, $friends);
294
    }
295
}
296