Passed
Push — master ( bd5724...8a312b )
by
unknown
01:47
created
src/Provider/QQ.php 2 patches
Indentation   +122 added lines, -122 removed lines patch added patch discarded remove patch
@@ -12,127 +12,127 @@
 block discarded – undo
12 12
  */
13 13
 class QQ extends OAuth2
14 14
 {
15
-    /**
16
-     * {@inheritdoc}
17
-     */
18
-    protected $scope = 'get_user_info';
19
-
20
-    /**
21
-     * {@inheritdoc}
22
-     */
23
-    protected $apiBaseUrl = 'https://graph.qq.com/oauth2.0/';
24
-
25
-    /**
26
-     * {@inheritdoc}
27
-     */
28
-    protected $authorizeUrl = 'https://graph.qq.com/oauth2.0/authorize';
29
-
30
-    /**
31
-     * {@inheritdoc}
32
-     */
33
-    protected $accessTokenUrl = 'https://graph.qq.com/oauth2.0/token';
34
-
35
-    /**
36
-     * {@ịnheritdoc}
37
-     */
38
-    protected $accessTokenInfoUrl = 'https://graph.qq.com/oauth2.0/me';
39
-
40
-    /**
41
-     * User Information Endpoint
42
-     * @var string
43
-     */
44
-    protected $accessUserInfo = 'https://graph.qq.com/user/get_user_info';
45
-
46
-    /**
47
-     * {@inheritdoc}
48
-     */
49
-    protected $tokenExchangeMethod = 'GET';
50
-
51
-    /**
52
-     * {@inheritdoc}
53
-     */
54
-    protected $tokenRefreshMethod = 'GET';
55
-
56
-    /**
57
-     * {@inheritdoc}
58
-     */
59
-    protected $apiDocumentation = ''; // Not available
60
-
61
-    /**
62
-     * {@inheritdoc}
63
-     */
64
-    protected $responseDataFormat = 'json';
15
+	/**
16
+	 * {@inheritdoc}
17
+	 */
18
+	protected $scope = 'get_user_info';
19
+
20
+	/**
21
+	 * {@inheritdoc}
22
+	 */
23
+	protected $apiBaseUrl = 'https://graph.qq.com/oauth2.0/';
24
+
25
+	/**
26
+	 * {@inheritdoc}
27
+	 */
28
+	protected $authorizeUrl = 'https://graph.qq.com/oauth2.0/authorize';
29
+
30
+	/**
31
+	 * {@inheritdoc}
32
+	 */
33
+	protected $accessTokenUrl = 'https://graph.qq.com/oauth2.0/token';
34
+
35
+	/**
36
+	 * {@ịnheritdoc}
37
+	 */
38
+	protected $accessTokenInfoUrl = 'https://graph.qq.com/oauth2.0/me';
39
+
40
+	/**
41
+	 * User Information Endpoint
42
+	 * @var string
43
+	 */
44
+	protected $accessUserInfo = 'https://graph.qq.com/user/get_user_info';
45
+
46
+	/**
47
+	 * {@inheritdoc}
48
+	 */
49
+	protected $tokenExchangeMethod = 'GET';
50
+
51
+	/**
52
+	 * {@inheritdoc}
53
+	 */
54
+	protected $tokenRefreshMethod = 'GET';
55
+
56
+	/**
57
+	 * {@inheritdoc}
58
+	 */
59
+	protected $apiDocumentation = ''; // Not available
60
+
61
+	/**
62
+	 * {@inheritdoc}
63
+	 */
64
+	protected $responseDataFormat = 'json';
65 65
     
66
-    /**
67
-     * {@inheritdoc}
68
-     */
69
-    protected function initialize()
70
-    {
71
-        parent::initialize();
72
-
73
-        if ($this->isRefreshTokenAvailable()) {
74
-            $this->tokenRefreshParameters += [
75
-                'client_id' => $this->clientId,
76
-                'client_secret' => $this->clientSecret,
77
-            ];
78
-        }
79
-
80
-        $this->apiRequestParameters = [
81
-            'access_token' => $this->getStoredData('access_token'),
82
-            'fmt' => $this>responseDataFormat
83
-        ];
84
-
85
-        $this->apiRequestHeaders = [];
86
-    }
87
-
88
-    /**
89
-     * {@inheritdoc}
90
-     */
91
-    protected function validateAccessTokenExchange($response)
92
-    {
93
-        $collection = parent::validateAccessTokenExchange($response);
94
-
95
-        $resp = $this->apiRequest($this->accessTokenInfoUrl);
96
-
97
-        if (!isset($resp->openid)) {
98
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
99
-        }
100
-
101
-        $this->storeData('openid', $resp->openid);
102
-
103
-        return $collection;
104
-    }
105
-
106
-    /**
107
-     * {@inheritdoc}
108
-     */
109
-    public function getUserProfile()
110
-    {
111
-        $openid = $this->getStoredData('openid');
112
-
113
-        $userRequestParameters = [
114
-            'oauth_consumer_key' => $this->clientId,
115
-            'openid' => $openid,
116
-            'format' => $this>responseDataFormat
117
-        ];
118
-
119
-        $response = $this->apiRequest($this->accessUserInfo, 'GET', $userRequestParameters);
120
-
121
-        $data = new Data\Collection($response);
122
-
123
-        if ($data->get('ret') < 0) {
124
-            throw new UnexpectedApiResponseException('Provider API returned an error: ' . $data->get('msg'));
125
-        }
126
-
127
-        $userProfile = new Profile();
128
-
129
-        $userProfile->identifier = $openid;
130
-        $userProfile->displayName = $data->get('nickname');
131
-        $userProfile->photoURL = $data->get('figureurl_2');
132
-        $userProfile->gender = $data->get('gender');
133
-        $userProfile->region = $data->get('province');
134
-        $userProfile->city = $data->get('city');
135
-
136
-        return $userProfile;
137
-    }
66
+	/**
67
+	 * {@inheritdoc}
68
+	 */
69
+	protected function initialize()
70
+	{
71
+		parent::initialize();
72
+
73
+		if ($this->isRefreshTokenAvailable()) {
74
+			$this->tokenRefreshParameters += [
75
+				'client_id' => $this->clientId,
76
+				'client_secret' => $this->clientSecret,
77
+			];
78
+		}
79
+
80
+		$this->apiRequestParameters = [
81
+			'access_token' => $this->getStoredData('access_token'),
82
+			'fmt' => $this>responseDataFormat
83
+		];
84
+
85
+		$this->apiRequestHeaders = [];
86
+	}
87
+
88
+	/**
89
+	 * {@inheritdoc}
90
+	 */
91
+	protected function validateAccessTokenExchange($response)
92
+	{
93
+		$collection = parent::validateAccessTokenExchange($response);
94
+
95
+		$resp = $this->apiRequest($this->accessTokenInfoUrl);
96
+
97
+		if (!isset($resp->openid)) {
98
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
99
+		}
100
+
101
+		$this->storeData('openid', $resp->openid);
102
+
103
+		return $collection;
104
+	}
105
+
106
+	/**
107
+	 * {@inheritdoc}
108
+	 */
109
+	public function getUserProfile()
110
+	{
111
+		$openid = $this->getStoredData('openid');
112
+
113
+		$userRequestParameters = [
114
+			'oauth_consumer_key' => $this->clientId,
115
+			'openid' => $openid,
116
+			'format' => $this>responseDataFormat
117
+		];
118
+
119
+		$response = $this->apiRequest($this->accessUserInfo, 'GET', $userRequestParameters);
120
+
121
+		$data = new Data\Collection($response);
122
+
123
+		if ($data->get('ret') < 0) {
124
+			throw new UnexpectedApiResponseException('Provider API returned an error: ' . $data->get('msg'));
125
+		}
126
+
127
+		$userProfile = new Profile();
128
+
129
+		$userProfile->identifier = $openid;
130
+		$userProfile->displayName = $data->get('nickname');
131
+		$userProfile->photoURL = $data->get('figureurl_2');
132
+		$userProfile->gender = $data->get('gender');
133
+		$userProfile->region = $data->get('province');
134
+		$userProfile->city = $data->get('city');
135
+
136
+		return $userProfile;
137
+	}
138 138
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -79,7 +79,7 @@  discard block
 block discarded – undo
79 79
 
80 80
         $this->apiRequestParameters = [
81 81
             'access_token' => $this->getStoredData('access_token'),
82
-            'fmt' => $this>responseDataFormat
82
+            'fmt' => $this > responseDataFormat
83 83
         ];
84 84
 
85 85
         $this->apiRequestHeaders = [];
@@ -94,7 +94,7 @@  discard block
 block discarded – undo
94 94
 
95 95
         $resp = $this->apiRequest($this->accessTokenInfoUrl);
96 96
 
97
-        if (!isset($resp->openid)) {
97
+        if ( ! isset($resp->openid)) {
98 98
             throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
99 99
         }
100 100
 
@@ -113,7 +113,7 @@  discard block
 block discarded – undo
113 113
         $userRequestParameters = [
114 114
             'oauth_consumer_key' => $this->clientId,
115 115
             'openid' => $openid,
116
-            'format' => $this>responseDataFormat
116
+            'format' => $this > responseDataFormat
117 117
         ];
118 118
 
119 119
         $response = $this->apiRequest($this->accessUserInfo, 'GET', $userRequestParameters);
@@ -121,7 +121,7 @@  discard block
 block discarded – undo
121 121
         $data = new Data\Collection($response);
122 122
 
123 123
         if ($data->get('ret') < 0) {
124
-            throw new UnexpectedApiResponseException('Provider API returned an error: ' . $data->get('msg'));
124
+            throw new UnexpectedApiResponseException('Provider API returned an error: '.$data->get('msg'));
125 125
         }
126 126
 
127 127
         $userProfile = new Profile();
Please login to merge, or discard this patch.
src/Provider/Facebook.php 2 patches
Indentation   +509 added lines, -509 removed lines patch added patch discarded remove patch
@@ -51,513 +51,513 @@
 block discarded – undo
51 51
  */
52 52
 class Facebook extends OAuth2
53 53
 {
54
-    /**
55
-     * {@inheritdoc}
56
-     */
57
-    protected $scope = 'email, public_profile';
58
-
59
-    /**
60
-     * {@inheritdoc}
61
-     */
62
-    protected $apiBaseUrl = 'https://graph.facebook.com/v8.0/';
63
-
64
-    /**
65
-     * {@inheritdoc}
66
-     */
67
-    protected $authorizeUrl = 'https://www.facebook.com/dialog/oauth';
68
-
69
-    /**
70
-     * {@inheritdoc}
71
-     */
72
-    protected $accessTokenUrl = 'https://graph.facebook.com/oauth/access_token';
73
-
74
-    /**
75
-     * {@inheritdoc}
76
-     */
77
-    protected $apiDocumentation = 'https://developers.facebook.com/docs/facebook-login/overview';
78
-
79
-    /**
80
-     * @var string Profile URL template as the fallback when no `link` returned from the API.
81
-     */
82
-    protected $profileUrlTemplate = 'https://www.facebook.com/%s';
83
-
84
-    /**
85
-     * {@inheritdoc}
86
-     */
87
-    protected function initialize()
88
-    {
89
-        parent::initialize();
90
-
91
-        // Require proof on all Facebook api calls
92
-        // https://developers.facebook.com/docs/graph-api/securing-requests#appsecret_proof
93
-        if ($accessToken = $this->getStoredData('access_token')) {
94
-            $this->apiRequestParameters['appsecret_proof'] = hash_hmac('sha256', $accessToken, $this->clientSecret);
95
-        }
96
-    }
97
-
98
-    /**
99
-     * {@inheritdoc}
100
-     */
101
-    public function maintainToken()
102
-    {
103
-        if (!$this->isConnected()) {
104
-            return;
105
-        }
106
-
107
-        // Handle token exchange prior to the standard handler for an API request
108
-        $exchange_by_expiry_days = $this->config->get('exchange_by_expiry_days') ?: 45;
109
-        if ($exchange_by_expiry_days !== null) {
110
-            $projected_timestamp = time() + 60 * 60 * 24 * $exchange_by_expiry_days;
111
-            if (!$this->hasAccessTokenExpired() && $this->hasAccessTokenExpired($projected_timestamp)) {
112
-                $this->exchangeAccessToken();
113
-            }
114
-        }
115
-    }
116
-
117
-    /**
118
-     * Exchange the Access Token with one that expires further in the future.
119
-     *
120
-     * @return string Raw Provider API response
121
-     * @throws \Hybridauth\Exception\HttpClientFailureException
122
-     * @throws \Hybridauth\Exception\HttpRequestFailedException
123
-     * @throws \Hybridauth\Exception\InvalidAccessTokenException
124
-     */
125
-    public function exchangeAccessToken()
126
-    {
127
-        $exchangeTokenParameters = [
128
-            'grant_type' => 'fb_exchange_token',
129
-            'client_id' => $this->clientId,
130
-            'client_secret' => $this->clientSecret,
131
-            'fb_exchange_token' => $this->getStoredData('access_token'),
132
-        ];
133
-
134
-        $response = $this->httpClient->request(
135
-            $this->accessTokenUrl,
136
-            'GET',
137
-            $exchangeTokenParameters
138
-        );
139
-
140
-        $this->validateApiResponse('Unable to exchange the access token');
141
-
142
-        $this->validateAccessTokenExchange($response);
143
-
144
-        return $response;
145
-    }
146
-
147
-    /**
148
-     * {@inheritdoc}
149
-     */
150
-    public function getUserProfile()
151
-    {
152
-        return $this->getUserProfileFromOIDCToken() ?? $this->getUserProfileFromAccessToken();
153
-    }
154
-
155
-    /**
156
-     * Retrieve the user data from access token.
157
-     *
158
-     * @return \Hybridauth\User\Profile
159
-     */
160
-    public function getUserProfileFromAccessToken()
161
-    {
162
-        $fields = [
163
-            'id',
164
-            'name',
165
-            'first_name',
166
-            'last_name',
167
-            'website',
168
-            'locale',
169
-            'about',
170
-            'email',
171
-            'hometown',
172
-            'birthday',
173
-        ];
174
-
175
-        if (strpos($this->scope, 'user_link') !== false) {
176
-            $fields[] = 'link';
177
-        }
178
-
179
-        if (strpos($this->scope, 'user_gender') !== false) {
180
-            $fields[] = 'gender';
181
-        }
182
-
183
-        // Note that en_US is needed for gender fields to match convention.
184
-        $locale = $this->config->get('locale') ?: 'en_US';
185
-        $response = $this->apiRequest('me', 'GET', [
186
-            'fields' => implode(',', $fields),
187
-            'locale' => $locale,
188
-        ]);
189
-
190
-        $data = new Data\Collection($response);
191
-
192
-        if (!$data->exists('id')) {
193
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
194
-        }
195
-
196
-        $userProfile = new User\Profile();
197
-
198
-        $userProfile->identifier = $data->get('id');
199
-        $userProfile->displayName = $data->get('name');
200
-        $userProfile->firstName = $data->get('first_name');
201
-        $userProfile->lastName = $data->get('last_name');
202
-        $userProfile->profileURL = $data->get('link');
203
-        $userProfile->webSiteURL = $data->get('website');
204
-        $userProfile->gender = $data->get('gender');
205
-        $userProfile->language = $data->get('locale');
206
-        $userProfile->description = $data->get('about');
207
-        $userProfile->email = $data->get('email');
208
-
209
-        // Fallback for profile URL in case Facebook does not provide "pretty" link with username (if user set it).
210
-        if (empty($userProfile->profileURL)) {
211
-            $userProfile->profileURL = $this->getProfileUrl($userProfile->identifier);
212
-        }
213
-
214
-        $userProfile->region = $data->filter('hometown')->get('name');
215
-
216
-        $photoSize = $this->config->get('photo_size') ?: '150';
217
-
218
-        $userProfile->photoURL = $this->apiBaseUrl . $userProfile->identifier;
219
-        $userProfile->photoURL .= '/picture?width=' . $photoSize . '&height=' . $photoSize;
220
-
221
-        $userProfile->emailVerified = $userProfile->email;
222
-
223
-        $userProfile = $this->fetchUserRegion($userProfile);
224
-
225
-        $userProfile = $this->fetchBirthday($userProfile, $data->get('birthday'));
226
-
227
-        return $userProfile;
228
-    }
229
-
230
-    /**
231
-     * Get the user profile from OIDC token.
232
-     *
233
-     * @return \Hybridauth\User\Profile
234
-     */
235
-    public function getUserProfileFromOIDCToken()
236
-    {
237
-        $accessToken = $this->getStoredData('access_token');
238
-
239
-        $kid = $this->getKidFromOLDCToken($accessToken);
240
-
241
-        if (!$kid) {
242
-            return null;
243
-        }
244
-
245
-        $clientId = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
246
-
247
-        if (!$clientId) {
248
-            throw new InvalidApplicationCredentialsException(
249
-                'Missing parameter id: your client id is required to generate the JWS token.'
250
-            );
251
-        }
252
-
253
-        $response = $this->apiRequest('https://www.facebook.com/.well-known/oauth/openid/jwks/');
254
-
255
-        $publicKeys = new Data\Collection($response);
256
-
257
-        if (!$publicKeys->exists('keys') || !$publicKeys->get('keys')) {
258
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
259
-        }
260
-
261
-        $filteredKeys = array_filter($publicKeys->get('keys'), function ($k) use ($kid) {
262
-            return $k->kid === $kid;
263
-        });
264
-
265
-        if (empty($filteredKeys)) {
266
-            throw new UnexpectedValueException('Unable to find key with kid: ' . $kid);
267
-        }
268
-
269
-        $jwk = array_shift($filteredKeys);
270
-
271
-        $keyData = [
272
-            'e' => new BigInteger(base64_decode($jwk->e), 256),
273
-            'n' => new BigInteger(base64_decode(strtr($jwk->n, '-_', '+/'), true), 256),
274
-        ];
275
-
276
-        $pem = (string) PublicKeyLoader::load($keyData)->withHash('sha1')->withMGFHash('sha1');
277
-
278
-        $payload = JWT::decode($accessToken, new Key($pem, $jwk->alg));
279
-
280
-        $data = new Data\Collection($payload);
281
-
282
-        if ($data->get('iss') !== 'https://www.facebook.com') {
283
-            throw new UnexpectedValueException('Invalid issuer');
284
-        } elseif ($data->get('aud') !== $clientId) {
285
-            throw new UnexpectedValueException('Invalid audience');
286
-        }
287
-
288
-        $userProfile = new User\Profile();
289
-        $userProfile->identifier = $data->get('sub');
290
-        $userProfile->email = $data->get('email');
291
-        $userProfile->firstName = $data->get('given_name');
292
-        $userProfile->lastName = $data->get('family_name');
293
-        $userProfile->displayName = $userProfile->firstName.' '.$userProfile->lastName;
294
-        $userProfile->photoURL = $data->get('picture');
295
-        // Fallback for profile URL in case Facebook does not provide "pretty" link with username (if user set it).
296
-        if (empty($userProfile->profileURL)) {
297
-            $userProfile->profileURL = $this->getProfileUrl($userProfile->identifier);
298
-        }
299
-
300
-        return $userProfile;
301
-    }
302
-
303
-    /**
304
-     * Retrieve the user region.
305
-     *
306
-     * @param User\Profile $userProfile
307
-     *
308
-     * @return \Hybridauth\User\Profile
309
-     */
310
-    protected function fetchUserRegion(User\Profile $userProfile)
311
-    {
312
-        if (!empty($userProfile->region)) {
313
-            $regionArr = explode(',', $userProfile->region);
314
-
315
-            if (count($regionArr) > 1) {
316
-                $userProfile->city = trim($regionArr[0]);
317
-                $userProfile->country = trim($regionArr[1]);
318
-            }
319
-        }
320
-
321
-        return $userProfile;
322
-    }
323
-
324
-    /**
325
-     * Retrieve the user birthday.
326
-     *
327
-     * @param User\Profile $userProfile
328
-     * @param string $birthday
329
-     *
330
-     * @return \Hybridauth\User\Profile
331
-     */
332
-    protected function fetchBirthday(User\Profile $userProfile, $birthday)
333
-    {
334
-        $result = (new Data\Parser())->parseBirthday($birthday);
335
-
336
-        $userProfile->birthYear = (int)$result[0];
337
-        $userProfile->birthMonth = (int)$result[1];
338
-        $userProfile->birthDay = (int)$result[2];
339
-
340
-        return $userProfile;
341
-    }
342
-
343
-    /**
344
-     * /v2.0/me/friends only returns the user's friends who also use the app.
345
-     * In the cases where you want to let people tag their friends in stories published by your app,
346
-     * you can use the Taggable Friends API.
347
-     *
348
-     * https://developers.facebook.com/docs/apps/faq#unable_full_friend_list
349
-     */
350
-    public function getUserContacts()
351
-    {
352
-        $contacts = [];
353
-
354
-        $apiUrl = 'me/friends?fields=link,name';
355
-
356
-        do {
357
-            $response = $this->apiRequest($apiUrl);
358
-
359
-            $data = new Data\Collection($response);
360
-
361
-            if (!$data->exists('data')) {
362
-                throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
363
-            }
364
-
365
-            if (!$data->filter('data')->isEmpty()) {
366
-                foreach ($data->filter('data')->toArray() as $item) {
367
-                    $contacts[] = $this->fetchUserContact($item);
368
-                }
369
-            }
370
-
371
-            if ($data->filter('paging')->exists('next')) {
372
-                $apiUrl = $data->filter('paging')->get('next');
373
-
374
-                $pagedList = true;
375
-            } else {
376
-                $pagedList = false;
377
-            }
378
-        } while ($pagedList);
379
-
380
-        return $contacts;
381
-    }
382
-
383
-    /**
384
-     * Parse the user contact.
385
-     *
386
-     * @param array $item
387
-     *
388
-     * @return \Hybridauth\User\Contact
389
-     */
390
-    protected function fetchUserContact($item)
391
-    {
392
-        $userContact = new User\Contact();
393
-
394
-        $item = new Data\Collection($item);
395
-
396
-        $userContact->identifier = $item->get('id');
397
-        $userContact->displayName = $item->get('name');
398
-
399
-        $userContact->profileURL = $item->exists('link')
400
-            ?: $this->getProfileUrl($userContact->identifier);
401
-
402
-        $userContact->photoURL = $this->apiBaseUrl . $userContact->identifier . '/picture?width=150&height=150';
403
-
404
-        return $userContact;
405
-    }
406
-
407
-    /**
408
-     * {@inheritdoc}
409
-     */
410
-    public function setPageStatus($status, $pageId)
411
-    {
412
-        $status = is_string($status) ? ['message' => $status] : $status;
413
-
414
-        // Post on user wall.
415
-        if ($pageId === 'me') {
416
-            return $this->setUserStatus($status);
417
-        }
418
-
419
-        // Retrieve writable user pages and filter by given one.
420
-        $pages = $this->getUserPages(true);
421
-        $pages = array_filter($pages, function ($page) use ($pageId) {
422
-            return $page->id == $pageId;
423
-        });
424
-
425
-        if (!$pages) {
426
-            throw new InvalidArgumentException('Could not find a page with given id.');
427
-        }
428
-
429
-        $page = reset($pages);
430
-
431
-        // Use page access token instead of user access token.
432
-        $headers = [
433
-            'Authorization' => 'Bearer ' . $page->access_token,
434
-        ];
435
-
436
-        // Refresh proof for API call.
437
-        $parameters = $status + [
438
-                'appsecret_proof' => hash_hmac('sha256', $page->access_token, $this->clientSecret),
439
-            ];
440
-
441
-        $response = $this->apiRequest("{$pageId}/feed", 'POST', $parameters, $headers);
442
-
443
-        return $response;
444
-    }
445
-
446
-    /**
447
-     * {@inheritdoc}
448
-     */
449
-    public function getUserPages($writable = false)
450
-    {
451
-        $pages = $this->apiRequest('me/accounts');
452
-
453
-        if (!$writable) {
454
-            return $pages->data;
455
-        }
456
-
457
-        // Filter user pages by CREATE_CONTENT permission.
458
-        return array_filter($pages->data, function ($page) {
459
-            return in_array('CREATE_CONTENT', $page->tasks);
460
-        });
461
-    }
462
-
463
-    /**
464
-     * {@inheritdoc}
465
-     */
466
-    public function getUserActivity($stream = 'me')
467
-    {
468
-        $apiUrl = $stream == 'me' ? 'me/feed' : 'me/home';
469
-
470
-        $response = $this->apiRequest($apiUrl);
471
-
472
-        $data = new Data\Collection($response);
473
-
474
-        if (!$data->exists('data')) {
475
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
476
-        }
477
-
478
-        $activities = [];
479
-
480
-        foreach ($data->filter('data')->toArray() as $item) {
481
-            $activities[] = $this->fetchUserActivity($item);
482
-        }
483
-
484
-        return $activities;
485
-    }
486
-
487
-    /**
488
-     * @param $item
489
-     *
490
-     * @return User\Activity
491
-     */
492
-    protected function fetchUserActivity($item)
493
-    {
494
-        $userActivity = new User\Activity();
495
-
496
-        $item = new Data\Collection($item);
497
-
498
-        $userActivity->id = $item->get('id');
499
-        $userActivity->date = $item->get('created_time');
500
-
501
-        if ('video' == $item->get('type') || 'link' == $item->get('type')) {
502
-            $userActivity->text = $item->get('link');
503
-        }
504
-
505
-        if (empty($userActivity->text) && $item->exists('story')) {
506
-            $userActivity->text = $item->get('link');
507
-        }
508
-
509
-        if (empty($userActivity->text) && $item->exists('message')) {
510
-            $userActivity->text = $item->get('message');
511
-        }
512
-
513
-        if (!empty($userActivity->text) && $item->exists('from')) {
514
-            $userActivity->user->identifier = $item->filter('from')->get('id');
515
-            $userActivity->user->displayName = $item->filter('from')->get('name');
516
-
517
-            $userActivity->user->profileURL = $this->getProfileUrl($userActivity->user->identifier);
518
-
519
-            $userActivity->user->photoURL = $this->apiBaseUrl . $userActivity->user->identifier;
520
-            $userActivity->user->photoURL .= '/picture?width=150&height=150';
521
-        }
522
-
523
-        return $userActivity;
524
-    }
525
-
526
-    /**
527
-     * Get key ID from OIDC token.
528
-     *
529
-     * @param string $accessToken
530
-     * @return string|null
531
-     */
532
-    private function getKidFromOLDCToken(string $accessToken): ?string
533
-    {
534
-        $segments = explode('.', $accessToken);
535
-
536
-        if (count($segments) !== 3) {
537
-            return null;
538
-        }
539
-
540
-        $payload = json_decode(base64_decode($segments[0] ?? ''));
541
-
542
-        if (!is_object($payload) || $payload?->kid === null) {
543
-            return null;
544
-        }
545
-
546
-        return $payload->kid;
547
-    }
548
-
549
-    /**
550
-     * Get profile URL.
551
-     *
552
-     * @param int $identity User ID.
553
-     * @return string|null NULL when identity is not provided.
554
-     */
555
-    protected function getProfileUrl($identity)
556
-    {
557
-        if (!is_numeric($identity)) {
558
-            return null;
559
-        }
560
-
561
-        return sprintf($this->profileUrlTemplate, $identity);
562
-    }
54
+	/**
55
+	 * {@inheritdoc}
56
+	 */
57
+	protected $scope = 'email, public_profile';
58
+
59
+	/**
60
+	 * {@inheritdoc}
61
+	 */
62
+	protected $apiBaseUrl = 'https://graph.facebook.com/v8.0/';
63
+
64
+	/**
65
+	 * {@inheritdoc}
66
+	 */
67
+	protected $authorizeUrl = 'https://www.facebook.com/dialog/oauth';
68
+
69
+	/**
70
+	 * {@inheritdoc}
71
+	 */
72
+	protected $accessTokenUrl = 'https://graph.facebook.com/oauth/access_token';
73
+
74
+	/**
75
+	 * {@inheritdoc}
76
+	 */
77
+	protected $apiDocumentation = 'https://developers.facebook.com/docs/facebook-login/overview';
78
+
79
+	/**
80
+	 * @var string Profile URL template as the fallback when no `link` returned from the API.
81
+	 */
82
+	protected $profileUrlTemplate = 'https://www.facebook.com/%s';
83
+
84
+	/**
85
+	 * {@inheritdoc}
86
+	 */
87
+	protected function initialize()
88
+	{
89
+		parent::initialize();
90
+
91
+		// Require proof on all Facebook api calls
92
+		// https://developers.facebook.com/docs/graph-api/securing-requests#appsecret_proof
93
+		if ($accessToken = $this->getStoredData('access_token')) {
94
+			$this->apiRequestParameters['appsecret_proof'] = hash_hmac('sha256', $accessToken, $this->clientSecret);
95
+		}
96
+	}
97
+
98
+	/**
99
+	 * {@inheritdoc}
100
+	 */
101
+	public function maintainToken()
102
+	{
103
+		if (!$this->isConnected()) {
104
+			return;
105
+		}
106
+
107
+		// Handle token exchange prior to the standard handler for an API request
108
+		$exchange_by_expiry_days = $this->config->get('exchange_by_expiry_days') ?: 45;
109
+		if ($exchange_by_expiry_days !== null) {
110
+			$projected_timestamp = time() + 60 * 60 * 24 * $exchange_by_expiry_days;
111
+			if (!$this->hasAccessTokenExpired() && $this->hasAccessTokenExpired($projected_timestamp)) {
112
+				$this->exchangeAccessToken();
113
+			}
114
+		}
115
+	}
116
+
117
+	/**
118
+	 * Exchange the Access Token with one that expires further in the future.
119
+	 *
120
+	 * @return string Raw Provider API response
121
+	 * @throws \Hybridauth\Exception\HttpClientFailureException
122
+	 * @throws \Hybridauth\Exception\HttpRequestFailedException
123
+	 * @throws \Hybridauth\Exception\InvalidAccessTokenException
124
+	 */
125
+	public function exchangeAccessToken()
126
+	{
127
+		$exchangeTokenParameters = [
128
+			'grant_type' => 'fb_exchange_token',
129
+			'client_id' => $this->clientId,
130
+			'client_secret' => $this->clientSecret,
131
+			'fb_exchange_token' => $this->getStoredData('access_token'),
132
+		];
133
+
134
+		$response = $this->httpClient->request(
135
+			$this->accessTokenUrl,
136
+			'GET',
137
+			$exchangeTokenParameters
138
+		);
139
+
140
+		$this->validateApiResponse('Unable to exchange the access token');
141
+
142
+		$this->validateAccessTokenExchange($response);
143
+
144
+		return $response;
145
+	}
146
+
147
+	/**
148
+	 * {@inheritdoc}
149
+	 */
150
+	public function getUserProfile()
151
+	{
152
+		return $this->getUserProfileFromOIDCToken() ?? $this->getUserProfileFromAccessToken();
153
+	}
154
+
155
+	/**
156
+	 * Retrieve the user data from access token.
157
+	 *
158
+	 * @return \Hybridauth\User\Profile
159
+	 */
160
+	public function getUserProfileFromAccessToken()
161
+	{
162
+		$fields = [
163
+			'id',
164
+			'name',
165
+			'first_name',
166
+			'last_name',
167
+			'website',
168
+			'locale',
169
+			'about',
170
+			'email',
171
+			'hometown',
172
+			'birthday',
173
+		];
174
+
175
+		if (strpos($this->scope, 'user_link') !== false) {
176
+			$fields[] = 'link';
177
+		}
178
+
179
+		if (strpos($this->scope, 'user_gender') !== false) {
180
+			$fields[] = 'gender';
181
+		}
182
+
183
+		// Note that en_US is needed for gender fields to match convention.
184
+		$locale = $this->config->get('locale') ?: 'en_US';
185
+		$response = $this->apiRequest('me', 'GET', [
186
+			'fields' => implode(',', $fields),
187
+			'locale' => $locale,
188
+		]);
189
+
190
+		$data = new Data\Collection($response);
191
+
192
+		if (!$data->exists('id')) {
193
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
194
+		}
195
+
196
+		$userProfile = new User\Profile();
197
+
198
+		$userProfile->identifier = $data->get('id');
199
+		$userProfile->displayName = $data->get('name');
200
+		$userProfile->firstName = $data->get('first_name');
201
+		$userProfile->lastName = $data->get('last_name');
202
+		$userProfile->profileURL = $data->get('link');
203
+		$userProfile->webSiteURL = $data->get('website');
204
+		$userProfile->gender = $data->get('gender');
205
+		$userProfile->language = $data->get('locale');
206
+		$userProfile->description = $data->get('about');
207
+		$userProfile->email = $data->get('email');
208
+
209
+		// Fallback for profile URL in case Facebook does not provide "pretty" link with username (if user set it).
210
+		if (empty($userProfile->profileURL)) {
211
+			$userProfile->profileURL = $this->getProfileUrl($userProfile->identifier);
212
+		}
213
+
214
+		$userProfile->region = $data->filter('hometown')->get('name');
215
+
216
+		$photoSize = $this->config->get('photo_size') ?: '150';
217
+
218
+		$userProfile->photoURL = $this->apiBaseUrl . $userProfile->identifier;
219
+		$userProfile->photoURL .= '/picture?width=' . $photoSize . '&height=' . $photoSize;
220
+
221
+		$userProfile->emailVerified = $userProfile->email;
222
+
223
+		$userProfile = $this->fetchUserRegion($userProfile);
224
+
225
+		$userProfile = $this->fetchBirthday($userProfile, $data->get('birthday'));
226
+
227
+		return $userProfile;
228
+	}
229
+
230
+	/**
231
+	 * Get the user profile from OIDC token.
232
+	 *
233
+	 * @return \Hybridauth\User\Profile
234
+	 */
235
+	public function getUserProfileFromOIDCToken()
236
+	{
237
+		$accessToken = $this->getStoredData('access_token');
238
+
239
+		$kid = $this->getKidFromOLDCToken($accessToken);
240
+
241
+		if (!$kid) {
242
+			return null;
243
+		}
244
+
245
+		$clientId = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
246
+
247
+		if (!$clientId) {
248
+			throw new InvalidApplicationCredentialsException(
249
+				'Missing parameter id: your client id is required to generate the JWS token.'
250
+			);
251
+		}
252
+
253
+		$response = $this->apiRequest('https://www.facebook.com/.well-known/oauth/openid/jwks/');
254
+
255
+		$publicKeys = new Data\Collection($response);
256
+
257
+		if (!$publicKeys->exists('keys') || !$publicKeys->get('keys')) {
258
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
259
+		}
260
+
261
+		$filteredKeys = array_filter($publicKeys->get('keys'), function ($k) use ($kid) {
262
+			return $k->kid === $kid;
263
+		});
264
+
265
+		if (empty($filteredKeys)) {
266
+			throw new UnexpectedValueException('Unable to find key with kid: ' . $kid);
267
+		}
268
+
269
+		$jwk = array_shift($filteredKeys);
270
+
271
+		$keyData = [
272
+			'e' => new BigInteger(base64_decode($jwk->e), 256),
273
+			'n' => new BigInteger(base64_decode(strtr($jwk->n, '-_', '+/'), true), 256),
274
+		];
275
+
276
+		$pem = (string) PublicKeyLoader::load($keyData)->withHash('sha1')->withMGFHash('sha1');
277
+
278
+		$payload = JWT::decode($accessToken, new Key($pem, $jwk->alg));
279
+
280
+		$data = new Data\Collection($payload);
281
+
282
+		if ($data->get('iss') !== 'https://www.facebook.com') {
283
+			throw new UnexpectedValueException('Invalid issuer');
284
+		} elseif ($data->get('aud') !== $clientId) {
285
+			throw new UnexpectedValueException('Invalid audience');
286
+		}
287
+
288
+		$userProfile = new User\Profile();
289
+		$userProfile->identifier = $data->get('sub');
290
+		$userProfile->email = $data->get('email');
291
+		$userProfile->firstName = $data->get('given_name');
292
+		$userProfile->lastName = $data->get('family_name');
293
+		$userProfile->displayName = $userProfile->firstName.' '.$userProfile->lastName;
294
+		$userProfile->photoURL = $data->get('picture');
295
+		// Fallback for profile URL in case Facebook does not provide "pretty" link with username (if user set it).
296
+		if (empty($userProfile->profileURL)) {
297
+			$userProfile->profileURL = $this->getProfileUrl($userProfile->identifier);
298
+		}
299
+
300
+		return $userProfile;
301
+	}
302
+
303
+	/**
304
+	 * Retrieve the user region.
305
+	 *
306
+	 * @param User\Profile $userProfile
307
+	 *
308
+	 * @return \Hybridauth\User\Profile
309
+	 */
310
+	protected function fetchUserRegion(User\Profile $userProfile)
311
+	{
312
+		if (!empty($userProfile->region)) {
313
+			$regionArr = explode(',', $userProfile->region);
314
+
315
+			if (count($regionArr) > 1) {
316
+				$userProfile->city = trim($regionArr[0]);
317
+				$userProfile->country = trim($regionArr[1]);
318
+			}
319
+		}
320
+
321
+		return $userProfile;
322
+	}
323
+
324
+	/**
325
+	 * Retrieve the user birthday.
326
+	 *
327
+	 * @param User\Profile $userProfile
328
+	 * @param string $birthday
329
+	 *
330
+	 * @return \Hybridauth\User\Profile
331
+	 */
332
+	protected function fetchBirthday(User\Profile $userProfile, $birthday)
333
+	{
334
+		$result = (new Data\Parser())->parseBirthday($birthday);
335
+
336
+		$userProfile->birthYear = (int)$result[0];
337
+		$userProfile->birthMonth = (int)$result[1];
338
+		$userProfile->birthDay = (int)$result[2];
339
+
340
+		return $userProfile;
341
+	}
342
+
343
+	/**
344
+	 * /v2.0/me/friends only returns the user's friends who also use the app.
345
+	 * In the cases where you want to let people tag their friends in stories published by your app,
346
+	 * you can use the Taggable Friends API.
347
+	 *
348
+	 * https://developers.facebook.com/docs/apps/faq#unable_full_friend_list
349
+	 */
350
+	public function getUserContacts()
351
+	{
352
+		$contacts = [];
353
+
354
+		$apiUrl = 'me/friends?fields=link,name';
355
+
356
+		do {
357
+			$response = $this->apiRequest($apiUrl);
358
+
359
+			$data = new Data\Collection($response);
360
+
361
+			if (!$data->exists('data')) {
362
+				throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
363
+			}
364
+
365
+			if (!$data->filter('data')->isEmpty()) {
366
+				foreach ($data->filter('data')->toArray() as $item) {
367
+					$contacts[] = $this->fetchUserContact($item);
368
+				}
369
+			}
370
+
371
+			if ($data->filter('paging')->exists('next')) {
372
+				$apiUrl = $data->filter('paging')->get('next');
373
+
374
+				$pagedList = true;
375
+			} else {
376
+				$pagedList = false;
377
+			}
378
+		} while ($pagedList);
379
+
380
+		return $contacts;
381
+	}
382
+
383
+	/**
384
+	 * Parse the user contact.
385
+	 *
386
+	 * @param array $item
387
+	 *
388
+	 * @return \Hybridauth\User\Contact
389
+	 */
390
+	protected function fetchUserContact($item)
391
+	{
392
+		$userContact = new User\Contact();
393
+
394
+		$item = new Data\Collection($item);
395
+
396
+		$userContact->identifier = $item->get('id');
397
+		$userContact->displayName = $item->get('name');
398
+
399
+		$userContact->profileURL = $item->exists('link')
400
+			?: $this->getProfileUrl($userContact->identifier);
401
+
402
+		$userContact->photoURL = $this->apiBaseUrl . $userContact->identifier . '/picture?width=150&height=150';
403
+
404
+		return $userContact;
405
+	}
406
+
407
+	/**
408
+	 * {@inheritdoc}
409
+	 */
410
+	public function setPageStatus($status, $pageId)
411
+	{
412
+		$status = is_string($status) ? ['message' => $status] : $status;
413
+
414
+		// Post on user wall.
415
+		if ($pageId === 'me') {
416
+			return $this->setUserStatus($status);
417
+		}
418
+
419
+		// Retrieve writable user pages and filter by given one.
420
+		$pages = $this->getUserPages(true);
421
+		$pages = array_filter($pages, function ($page) use ($pageId) {
422
+			return $page->id == $pageId;
423
+		});
424
+
425
+		if (!$pages) {
426
+			throw new InvalidArgumentException('Could not find a page with given id.');
427
+		}
428
+
429
+		$page = reset($pages);
430
+
431
+		// Use page access token instead of user access token.
432
+		$headers = [
433
+			'Authorization' => 'Bearer ' . $page->access_token,
434
+		];
435
+
436
+		// Refresh proof for API call.
437
+		$parameters = $status + [
438
+				'appsecret_proof' => hash_hmac('sha256', $page->access_token, $this->clientSecret),
439
+			];
440
+
441
+		$response = $this->apiRequest("{$pageId}/feed", 'POST', $parameters, $headers);
442
+
443
+		return $response;
444
+	}
445
+
446
+	/**
447
+	 * {@inheritdoc}
448
+	 */
449
+	public function getUserPages($writable = false)
450
+	{
451
+		$pages = $this->apiRequest('me/accounts');
452
+
453
+		if (!$writable) {
454
+			return $pages->data;
455
+		}
456
+
457
+		// Filter user pages by CREATE_CONTENT permission.
458
+		return array_filter($pages->data, function ($page) {
459
+			return in_array('CREATE_CONTENT', $page->tasks);
460
+		});
461
+	}
462
+
463
+	/**
464
+	 * {@inheritdoc}
465
+	 */
466
+	public function getUserActivity($stream = 'me')
467
+	{
468
+		$apiUrl = $stream == 'me' ? 'me/feed' : 'me/home';
469
+
470
+		$response = $this->apiRequest($apiUrl);
471
+
472
+		$data = new Data\Collection($response);
473
+
474
+		if (!$data->exists('data')) {
475
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
476
+		}
477
+
478
+		$activities = [];
479
+
480
+		foreach ($data->filter('data')->toArray() as $item) {
481
+			$activities[] = $this->fetchUserActivity($item);
482
+		}
483
+
484
+		return $activities;
485
+	}
486
+
487
+	/**
488
+	 * @param $item
489
+	 *
490
+	 * @return User\Activity
491
+	 */
492
+	protected function fetchUserActivity($item)
493
+	{
494
+		$userActivity = new User\Activity();
495
+
496
+		$item = new Data\Collection($item);
497
+
498
+		$userActivity->id = $item->get('id');
499
+		$userActivity->date = $item->get('created_time');
500
+
501
+		if ('video' == $item->get('type') || 'link' == $item->get('type')) {
502
+			$userActivity->text = $item->get('link');
503
+		}
504
+
505
+		if (empty($userActivity->text) && $item->exists('story')) {
506
+			$userActivity->text = $item->get('link');
507
+		}
508
+
509
+		if (empty($userActivity->text) && $item->exists('message')) {
510
+			$userActivity->text = $item->get('message');
511
+		}
512
+
513
+		if (!empty($userActivity->text) && $item->exists('from')) {
514
+			$userActivity->user->identifier = $item->filter('from')->get('id');
515
+			$userActivity->user->displayName = $item->filter('from')->get('name');
516
+
517
+			$userActivity->user->profileURL = $this->getProfileUrl($userActivity->user->identifier);
518
+
519
+			$userActivity->user->photoURL = $this->apiBaseUrl . $userActivity->user->identifier;
520
+			$userActivity->user->photoURL .= '/picture?width=150&height=150';
521
+		}
522
+
523
+		return $userActivity;
524
+	}
525
+
526
+	/**
527
+	 * Get key ID from OIDC token.
528
+	 *
529
+	 * @param string $accessToken
530
+	 * @return string|null
531
+	 */
532
+	private function getKidFromOLDCToken(string $accessToken): ?string
533
+	{
534
+		$segments = explode('.', $accessToken);
535
+
536
+		if (count($segments) !== 3) {
537
+			return null;
538
+		}
539
+
540
+		$payload = json_decode(base64_decode($segments[0] ?? ''));
541
+
542
+		if (!is_object($payload) || $payload?->kid === null) {
543
+			return null;
544
+		}
545
+
546
+		return $payload->kid;
547
+	}
548
+
549
+	/**
550
+	 * Get profile URL.
551
+	 *
552
+	 * @param int $identity User ID.
553
+	 * @return string|null NULL when identity is not provided.
554
+	 */
555
+	protected function getProfileUrl($identity)
556
+	{
557
+		if (!is_numeric($identity)) {
558
+			return null;
559
+		}
560
+
561
+		return sprintf($this->profileUrlTemplate, $identity);
562
+	}
563 563
 }
Please login to merge, or discard this patch.
Spacing   +27 added lines, -27 removed lines patch added patch discarded remove patch
@@ -100,7 +100,7 @@  discard block
 block discarded – undo
100 100
      */
101 101
     public function maintainToken()
102 102
     {
103
-        if (!$this->isConnected()) {
103
+        if ( ! $this->isConnected()) {
104 104
             return;
105 105
         }
106 106
 
@@ -108,7 +108,7 @@  discard block
 block discarded – undo
108 108
         $exchange_by_expiry_days = $this->config->get('exchange_by_expiry_days') ?: 45;
109 109
         if ($exchange_by_expiry_days !== null) {
110 110
             $projected_timestamp = time() + 60 * 60 * 24 * $exchange_by_expiry_days;
111
-            if (!$this->hasAccessTokenExpired() && $this->hasAccessTokenExpired($projected_timestamp)) {
111
+            if ( ! $this->hasAccessTokenExpired() && $this->hasAccessTokenExpired($projected_timestamp)) {
112 112
                 $this->exchangeAccessToken();
113 113
             }
114 114
         }
@@ -189,7 +189,7 @@  discard block
 block discarded – undo
189 189
 
190 190
         $data = new Data\Collection($response);
191 191
 
192
-        if (!$data->exists('id')) {
192
+        if ( ! $data->exists('id')) {
193 193
             throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
194 194
         }
195 195
 
@@ -215,8 +215,8 @@  discard block
 block discarded – undo
215 215
 
216 216
         $photoSize = $this->config->get('photo_size') ?: '150';
217 217
 
218
-        $userProfile->photoURL = $this->apiBaseUrl . $userProfile->identifier;
219
-        $userProfile->photoURL .= '/picture?width=' . $photoSize . '&height=' . $photoSize;
218
+        $userProfile->photoURL = $this->apiBaseUrl.$userProfile->identifier;
219
+        $userProfile->photoURL .= '/picture?width='.$photoSize.'&height='.$photoSize;
220 220
 
221 221
         $userProfile->emailVerified = $userProfile->email;
222 222
 
@@ -238,13 +238,13 @@  discard block
 block discarded – undo
238 238
 
239 239
         $kid = $this->getKidFromOLDCToken($accessToken);
240 240
 
241
-        if (!$kid) {
241
+        if ( ! $kid) {
242 242
             return null;
243 243
         }
244 244
 
245 245
         $clientId = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key');
246 246
 
247
-        if (!$clientId) {
247
+        if ( ! $clientId) {
248 248
             throw new InvalidApplicationCredentialsException(
249 249
                 'Missing parameter id: your client id is required to generate the JWS token.'
250 250
             );
@@ -254,16 +254,16 @@  discard block
 block discarded – undo
254 254
 
255 255
         $publicKeys = new Data\Collection($response);
256 256
 
257
-        if (!$publicKeys->exists('keys') || !$publicKeys->get('keys')) {
257
+        if ( ! $publicKeys->exists('keys') || ! $publicKeys->get('keys')) {
258 258
             throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
259 259
         }
260 260
 
261
-        $filteredKeys = array_filter($publicKeys->get('keys'), function ($k) use ($kid) {
261
+        $filteredKeys = array_filter($publicKeys->get('keys'), function($k) use ($kid) {
262 262
             return $k->kid === $kid;
263 263
         });
264 264
 
265 265
         if (empty($filteredKeys)) {
266
-            throw new UnexpectedValueException('Unable to find key with kid: ' . $kid);
266
+            throw new UnexpectedValueException('Unable to find key with kid: '.$kid);
267 267
         }
268 268
 
269 269
         $jwk = array_shift($filteredKeys);
@@ -309,7 +309,7 @@  discard block
 block discarded – undo
309 309
      */
310 310
     protected function fetchUserRegion(User\Profile $userProfile)
311 311
     {
312
-        if (!empty($userProfile->region)) {
312
+        if ( ! empty($userProfile->region)) {
313 313
             $regionArr = explode(',', $userProfile->region);
314 314
 
315 315
             if (count($regionArr) > 1) {
@@ -333,9 +333,9 @@  discard block
 block discarded – undo
333 333
     {
334 334
         $result = (new Data\Parser())->parseBirthday($birthday);
335 335
 
336
-        $userProfile->birthYear = (int)$result[0];
337
-        $userProfile->birthMonth = (int)$result[1];
338
-        $userProfile->birthDay = (int)$result[2];
336
+        $userProfile->birthYear = (int) $result[0];
337
+        $userProfile->birthMonth = (int) $result[1];
338
+        $userProfile->birthDay = (int) $result[2];
339 339
 
340 340
         return $userProfile;
341 341
     }
@@ -358,11 +358,11 @@  discard block
 block discarded – undo
358 358
 
359 359
             $data = new Data\Collection($response);
360 360
 
361
-            if (!$data->exists('data')) {
361
+            if ( ! $data->exists('data')) {
362 362
                 throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
363 363
             }
364 364
 
365
-            if (!$data->filter('data')->isEmpty()) {
365
+            if ( ! $data->filter('data')->isEmpty()) {
366 366
                 foreach ($data->filter('data')->toArray() as $item) {
367 367
                     $contacts[] = $this->fetchUserContact($item);
368 368
                 }
@@ -399,7 +399,7 @@  discard block
 block discarded – undo
399 399
         $userContact->profileURL = $item->exists('link')
400 400
             ?: $this->getProfileUrl($userContact->identifier);
401 401
 
402
-        $userContact->photoURL = $this->apiBaseUrl . $userContact->identifier . '/picture?width=150&height=150';
402
+        $userContact->photoURL = $this->apiBaseUrl.$userContact->identifier.'/picture?width=150&height=150';
403 403
 
404 404
         return $userContact;
405 405
     }
@@ -418,11 +418,11 @@  discard block
 block discarded – undo
418 418
 
419 419
         // Retrieve writable user pages and filter by given one.
420 420
         $pages = $this->getUserPages(true);
421
-        $pages = array_filter($pages, function ($page) use ($pageId) {
421
+        $pages = array_filter($pages, function($page) use ($pageId) {
422 422
             return $page->id == $pageId;
423 423
         });
424 424
 
425
-        if (!$pages) {
425
+        if ( ! $pages) {
426 426
             throw new InvalidArgumentException('Could not find a page with given id.');
427 427
         }
428 428
 
@@ -430,7 +430,7 @@  discard block
 block discarded – undo
430 430
 
431 431
         // Use page access token instead of user access token.
432 432
         $headers = [
433
-            'Authorization' => 'Bearer ' . $page->access_token,
433
+            'Authorization' => 'Bearer '.$page->access_token,
434 434
         ];
435 435
 
436 436
         // Refresh proof for API call.
@@ -450,12 +450,12 @@  discard block
 block discarded – undo
450 450
     {
451 451
         $pages = $this->apiRequest('me/accounts');
452 452
 
453
-        if (!$writable) {
453
+        if ( ! $writable) {
454 454
             return $pages->data;
455 455
         }
456 456
 
457 457
         // Filter user pages by CREATE_CONTENT permission.
458
-        return array_filter($pages->data, function ($page) {
458
+        return array_filter($pages->data, function($page) {
459 459
             return in_array('CREATE_CONTENT', $page->tasks);
460 460
         });
461 461
     }
@@ -471,7 +471,7 @@  discard block
 block discarded – undo
471 471
 
472 472
         $data = new Data\Collection($response);
473 473
 
474
-        if (!$data->exists('data')) {
474
+        if ( ! $data->exists('data')) {
475 475
             throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
476 476
         }
477 477
 
@@ -510,13 +510,13 @@  discard block
 block discarded – undo
510 510
             $userActivity->text = $item->get('message');
511 511
         }
512 512
 
513
-        if (!empty($userActivity->text) && $item->exists('from')) {
513
+        if ( ! empty($userActivity->text) && $item->exists('from')) {
514 514
             $userActivity->user->identifier = $item->filter('from')->get('id');
515 515
             $userActivity->user->displayName = $item->filter('from')->get('name');
516 516
 
517 517
             $userActivity->user->profileURL = $this->getProfileUrl($userActivity->user->identifier);
518 518
 
519
-            $userActivity->user->photoURL = $this->apiBaseUrl . $userActivity->user->identifier;
519
+            $userActivity->user->photoURL = $this->apiBaseUrl.$userActivity->user->identifier;
520 520
             $userActivity->user->photoURL .= '/picture?width=150&height=150';
521 521
         }
522 522
 
@@ -539,7 +539,7 @@  discard block
 block discarded – undo
539 539
 
540 540
         $payload = json_decode(base64_decode($segments[0] ?? ''));
541 541
 
542
-        if (!is_object($payload) || $payload?->kid === null) {
542
+        if ( ! is_object($payload) || $payload?->kid === null) {
543 543
             return null;
544 544
         }
545 545
 
@@ -554,7 +554,7 @@  discard block
 block discarded – undo
554 554
      */
555 555
     protected function getProfileUrl($identity)
556 556
     {
557
-        if (!is_numeric($identity)) {
557
+        if ( ! is_numeric($identity)) {
558 558
             return null;
559 559
         }
560 560
 
Please login to merge, or discard this patch.
src/Provider/MicrosoftGraph.php 2 patches
Indentation   +133 added lines, -133 removed lines patch added patch discarded remove patch
@@ -43,138 +43,138 @@
 block discarded – undo
43 43
  */
44 44
 class MicrosoftGraph extends OAuth2
45 45
 {
46
-    /**
47
-     * {@inheritdoc}
48
-     */
49
-    protected $scope = 'openid user.read contacts.read offline_access';
50
-
51
-    /**
52
-     * {@inheritdoc}
53
-     */
54
-    protected $apiBaseUrl = 'https://graph.microsoft.com/v1.0/';
55
-
56
-    /**
57
-     * {@inheritdoc}
58
-     */
59
-    protected $authorizeUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
60
-
61
-    /**
62
-     * {@inheritdoc}
63
-     */
64
-    protected $accessTokenUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
65
-
66
-    /**
67
-     * {@inheritdoc}
68
-     */
69
-    protected $apiDocumentation = 'https://developer.microsoft.com/en-us/graph/docs/concepts/php';
70
-
71
-    /**
72
-     * {@inheritdoc}
73
-     */
74
-    protected function initialize()
75
-    {
76
-        parent::initialize();
77
-
78
-        $this->AuthorizeUrlParameters += [
46
+	/**
47
+	 * {@inheritdoc}
48
+	 */
49
+	protected $scope = 'openid user.read contacts.read offline_access';
50
+
51
+	/**
52
+	 * {@inheritdoc}
53
+	 */
54
+	protected $apiBaseUrl = 'https://graph.microsoft.com/v1.0/';
55
+
56
+	/**
57
+	 * {@inheritdoc}
58
+	 */
59
+	protected $authorizeUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize';
60
+
61
+	/**
62
+	 * {@inheritdoc}
63
+	 */
64
+	protected $accessTokenUrl = 'https://login.microsoftonline.com/common/oauth2/v2.0/token';
65
+
66
+	/**
67
+	 * {@inheritdoc}
68
+	 */
69
+	protected $apiDocumentation = 'https://developer.microsoft.com/en-us/graph/docs/concepts/php';
70
+
71
+	/**
72
+	 * {@inheritdoc}
73
+	 */
74
+	protected function initialize()
75
+	{
76
+		parent::initialize();
77
+
78
+		$this->AuthorizeUrlParameters += [
79 79
 			'prompt' => 'consent',
80
-        ];
81
-
82
-        $tenant = $this->config->get('tenant');
83
-        if (!empty($tenant)) {
84
-            $adjustedEndpoints = [
85
-                'authorize_url' => str_replace('/common/', '/' . $tenant . '/', $this->authorizeUrl),
86
-                'access_token_url' => str_replace('/common/', '/' . $tenant . '/', $this->accessTokenUrl),
87
-            ];
88
-
89
-            $this->setApiEndpoints($adjustedEndpoints);
90
-        }
91
-
92
-        if ($this->isRefreshTokenAvailable()) {
93
-            $this->tokenRefreshParameters += [
94
-                'client_id' => $this->clientId,
95
-                'client_secret' => $this->clientSecret,
96
-            ];
97
-        }
98
-    }
99
-
100
-    /**
101
-     * {@inheritdoc}
102
-     */
103
-    public function getUserProfile()
104
-    {
105
-        $response = $this->apiRequest('me');
106
-
107
-        $data = new Data\Collection($response);
108
-
109
-        if (!$data->exists('id')) {
110
-            throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
111
-        }
112
-
113
-        $userProfile = new User\Profile();
114
-
115
-        $userProfile->identifier = $data->get('id');
116
-        $userProfile->displayName = $data->get('displayName');
117
-        $userProfile->firstName = $data->get('givenName');
118
-        $userProfile->lastName = $data->get('surname');
119
-        $userProfile->language = $data->get('preferredLanguage');
120
-
121
-        $userProfile->phone = $data->get('mobilePhone');
122
-        if (empty($userProfile->phone)) {
123
-            $businessPhones = $data->get('businessPhones');
124
-            if (isset($businessPhones[0])) {
125
-                $userProfile->phone = $businessPhones[0];
126
-            }
127
-        }
128
-
129
-        $userProfile->email = $data->get('mail');
130
-        if (empty($userProfile->email)) {
131
-            $email = $data->get('userPrincipalName');
132
-            if (strpos($email, '@') !== false) {
133
-                $userProfile->email = $email;
134
-            }
135
-        }
136
-
137
-        return $userProfile;
138
-    }
139
-
140
-    /**
141
-     * {@inheritdoc}
142
-     */
143
-    public function getUserContacts()
144
-    {
145
-        $apiUrl = 'me/contacts?$top=50';
146
-        $contacts = [];
147
-
148
-        do {
149
-            $response = $this->apiRequest($apiUrl);
150
-            $data = new Data\Collection($response);
151
-            if (!$data->exists('value')) {
152
-                throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
153
-            }
154
-            foreach ($data->filter('value')->toArray() as $entry) {
155
-                $entry = new Data\Collection($entry);
156
-                $userContact = new User\Contact();
157
-                $userContact->identifier = $entry->get('id');
158
-                $userContact->displayName = $entry->get('displayName');
159
-                $emailAddresses = $entry->get('emailAddresses');
160
-                if (!empty($emailAddresses)) {
161
-                    $userContact->email = $emailAddresses[0]->address;
162
-                }
163
-                // only add to collection if we have usefull data
164
-                if (!empty($userContact->displayName) || !empty($userContact->email)) {
165
-                    $contacts[] = $userContact;
166
-                }
167
-            }
168
-
169
-            if ($data->exists('@odata.nextLink')) {
170
-                $apiUrl = $data->get('@odata.nextLink');
171
-
172
-                $pagedList = true;
173
-            } else {
174
-                $pagedList = false;
175
-            }
176
-        } while ($pagedList);
177
-
178
-        return $contacts;
179
-    }
80
+		];
81
+
82
+		$tenant = $this->config->get('tenant');
83
+		if (!empty($tenant)) {
84
+			$adjustedEndpoints = [
85
+				'authorize_url' => str_replace('/common/', '/' . $tenant . '/', $this->authorizeUrl),
86
+				'access_token_url' => str_replace('/common/', '/' . $tenant . '/', $this->accessTokenUrl),
87
+			];
88
+
89
+			$this->setApiEndpoints($adjustedEndpoints);
90
+		}
91
+
92
+		if ($this->isRefreshTokenAvailable()) {
93
+			$this->tokenRefreshParameters += [
94
+				'client_id' => $this->clientId,
95
+				'client_secret' => $this->clientSecret,
96
+			];
97
+		}
98
+	}
99
+
100
+	/**
101
+	 * {@inheritdoc}
102
+	 */
103
+	public function getUserProfile()
104
+	{
105
+		$response = $this->apiRequest('me');
106
+
107
+		$data = new Data\Collection($response);
108
+
109
+		if (!$data->exists('id')) {
110
+			throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
111
+		}
112
+
113
+		$userProfile = new User\Profile();
114
+
115
+		$userProfile->identifier = $data->get('id');
116
+		$userProfile->displayName = $data->get('displayName');
117
+		$userProfile->firstName = $data->get('givenName');
118
+		$userProfile->lastName = $data->get('surname');
119
+		$userProfile->language = $data->get('preferredLanguage');
120
+
121
+		$userProfile->phone = $data->get('mobilePhone');
122
+		if (empty($userProfile->phone)) {
123
+			$businessPhones = $data->get('businessPhones');
124
+			if (isset($businessPhones[0])) {
125
+				$userProfile->phone = $businessPhones[0];
126
+			}
127
+		}
128
+
129
+		$userProfile->email = $data->get('mail');
130
+		if (empty($userProfile->email)) {
131
+			$email = $data->get('userPrincipalName');
132
+			if (strpos($email, '@') !== false) {
133
+				$userProfile->email = $email;
134
+			}
135
+		}
136
+
137
+		return $userProfile;
138
+	}
139
+
140
+	/**
141
+	 * {@inheritdoc}
142
+	 */
143
+	public function getUserContacts()
144
+	{
145
+		$apiUrl = 'me/contacts?$top=50';
146
+		$contacts = [];
147
+
148
+		do {
149
+			$response = $this->apiRequest($apiUrl);
150
+			$data = new Data\Collection($response);
151
+			if (!$data->exists('value')) {
152
+				throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
153
+			}
154
+			foreach ($data->filter('value')->toArray() as $entry) {
155
+				$entry = new Data\Collection($entry);
156
+				$userContact = new User\Contact();
157
+				$userContact->identifier = $entry->get('id');
158
+				$userContact->displayName = $entry->get('displayName');
159
+				$emailAddresses = $entry->get('emailAddresses');
160
+				if (!empty($emailAddresses)) {
161
+					$userContact->email = $emailAddresses[0]->address;
162
+				}
163
+				// only add to collection if we have usefull data
164
+				if (!empty($userContact->displayName) || !empty($userContact->email)) {
165
+					$contacts[] = $userContact;
166
+				}
167
+			}
168
+
169
+			if ($data->exists('@odata.nextLink')) {
170
+				$apiUrl = $data->get('@odata.nextLink');
171
+
172
+				$pagedList = true;
173
+			} else {
174
+				$pagedList = false;
175
+			}
176
+		} while ($pagedList);
177
+
178
+		return $contacts;
179
+	}
180 180
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -80,10 +80,10 @@  discard block
 block discarded – undo
80 80
         ];
81 81
 
82 82
         $tenant = $this->config->get('tenant');
83
-        if (!empty($tenant)) {
83
+        if ( ! empty($tenant)) {
84 84
             $adjustedEndpoints = [
85
-                'authorize_url' => str_replace('/common/', '/' . $tenant . '/', $this->authorizeUrl),
86
-                'access_token_url' => str_replace('/common/', '/' . $tenant . '/', $this->accessTokenUrl),
85
+                'authorize_url' => str_replace('/common/', '/'.$tenant.'/', $this->authorizeUrl),
86
+                'access_token_url' => str_replace('/common/', '/'.$tenant.'/', $this->accessTokenUrl),
87 87
             ];
88 88
 
89 89
             $this->setApiEndpoints($adjustedEndpoints);
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
 
107 107
         $data = new Data\Collection($response);
108 108
 
109
-        if (!$data->exists('id')) {
109
+        if ( ! $data->exists('id')) {
110 110
             throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
111 111
         }
112 112
 
@@ -148,7 +148,7 @@  discard block
 block discarded – undo
148 148
         do {
149 149
             $response = $this->apiRequest($apiUrl);
150 150
             $data = new Data\Collection($response);
151
-            if (!$data->exists('value')) {
151
+            if ( ! $data->exists('value')) {
152 152
                 throw new UnexpectedApiResponseException('Provider API returned an unexpected response.');
153 153
             }
154 154
             foreach ($data->filter('value')->toArray() as $entry) {
@@ -157,11 +157,11 @@  discard block
 block discarded – undo
157 157
                 $userContact->identifier = $entry->get('id');
158 158
                 $userContact->displayName = $entry->get('displayName');
159 159
                 $emailAddresses = $entry->get('emailAddresses');
160
-                if (!empty($emailAddresses)) {
160
+                if ( ! empty($emailAddresses)) {
161 161
                     $userContact->email = $emailAddresses[0]->address;
162 162
                 }
163 163
                 // only add to collection if we have usefull data
164
-                if (!empty($userContact->displayName) || !empty($userContact->email)) {
164
+                if ( ! empty($userContact->displayName) || ! empty($userContact->email)) {
165 165
                     $contacts[] = $userContact;
166 166
                 }
167 167
             }
Please login to merge, or discard this patch.
src/Hybridauth.php 2 patches
Indentation   +242 added lines, -242 removed lines patch added patch discarded remove patch
@@ -24,246 +24,246 @@
 block discarded – undo
24 24
  */
25 25
 class Hybridauth
26 26
 {
27
-    /**
28
-     * Hybridauth config.
29
-     *
30
-     * @var array
31
-     */
32
-    protected $config;
33
-
34
-    /**
35
-     * Storage.
36
-     *
37
-     * @var StorageInterface
38
-     */
39
-    protected $storage;
40
-
41
-    /**
42
-     * HttpClient.
43
-     *
44
-     * @var HttpClientInterface
45
-     */
46
-    protected $httpClient;
47
-
48
-    /**
49
-     * Logger.
50
-     *
51
-     * @var LoggerInterface
52
-     */
53
-    protected $logger;
54
-
55
-    /**
56
-     * @param array|string $config Array with configuration or Path to PHP file that will return array
57
-     * @param HttpClientInterface $httpClient
58
-     * @param StorageInterface $storage
59
-     * @param LoggerInterface $logger
60
-     *
61
-     * @throws InvalidArgumentException
62
-     */
63
-    public function __construct(
64
-        $config,
65
-        HttpClientInterface $httpClient = null,
66
-        StorageInterface $storage = null,
67
-        LoggerInterface $logger = null
68
-    ) {
69
-        if (is_string($config) && file_exists($config)) {
70
-            $config = include $config;
71
-        } elseif (!is_array($config)) {
72
-            throw new InvalidArgumentException('Hybridauth config does not exist on the given path.');
73
-        }
74
-
75
-        $this->config = $config + [
76
-                'debug_mode' => Logger::NONE,
77
-                'debug_file' => '',
78
-                'curl_options' => null,
79
-                'providers' => []
80
-            ];
81
-        $this->storage = $storage;
82
-        $this->logger = $logger;
83
-        $this->httpClient = $httpClient;
84
-    }
85
-
86
-    /**
87
-     * Instantiate the given provider and authentication or authorization protocol.
88
-     *
89
-     * If not authenticated yet, the user will be redirected to the provider's site for
90
-     * authentication/authorisation, otherwise it will simply return an instance of
91
-     * provider's adapter.
92
-     *
93
-     * @param string $name adapter's name (case insensitive)
94
-     *
95
-     * @return \Hybridauth\Adapter\AdapterInterface
96
-     * @throws InvalidArgumentException
97
-     * @throws UnexpectedValueException
98
-     */
99
-    public function authenticate($name)
100
-    {
101
-        $adapter = $this->getAdapter($name);
102
-
103
-        $adapter->authenticate();
104
-
105
-        return $adapter;
106
-    }
107
-
108
-    /**
109
-     * Returns a new instance of a provider's adapter by name
110
-     *
111
-     * @param string $name adapter's name (case insensitive)
112
-     *
113
-     * @return \Hybridauth\Adapter\AdapterInterface
114
-     * @throws InvalidArgumentException
115
-     * @throws UnexpectedValueException
116
-     */
117
-    public function getAdapter($name)
118
-    {
119
-        $config = $this->getProviderConfig($name);
120
-
121
-        $adapter = isset($config['adapter']) ? $config['adapter'] : sprintf('Hybridauth\\Provider\\%s', $name);
122
-
123
-        if (!class_exists($adapter)) {
124
-            $unexistingConfiguredAdapter = $adapter;
125
-            $adapter = null;
126
-            $fs = new \FilesystemIterator(__DIR__ . '/Provider/');
127
-            /** @var \SplFileInfo $file */
128
-            foreach ($fs as $file) {
129
-                if (!$file->isDir()) {
130
-                    $provider = strtok($file->getFilename(), '.');
131
-                    if (mb_strtolower($name) === mb_strtolower($provider)) {
132
-                        $adapter = sprintf('Hybridauth\\Provider\\%s', $provider);
133
-                        break;
134
-                    }
135
-                }
136
-            }
137
-            if ($adapter === null) {
138
-                throw new InvalidArgumentException("Unknown Provider (name: $name / configured: $unexistingConfiguredAdapter).");
139
-            }
140
-        }
141
-
142
-        return new $adapter($config, $this->httpClient, $this->storage, $this->logger);
143
-    }
144
-
145
-    /**
146
-     * Get provider config by name.
147
-     *
148
-     * @param string $name adapter's name (case insensitive)
149
-     *
150
-     * @throws UnexpectedValueException
151
-     * @throws InvalidArgumentException
152
-     *
153
-     * @return array
154
-     */
155
-    public function getProviderConfig($name)
156
-    {
157
-        $name = strtolower($name);
158
-
159
-        $providersConfig = array_change_key_case($this->config['providers'], CASE_LOWER);
160
-
161
-        if (!isset($providersConfig[$name])) {
162
-            throw new InvalidArgumentException('Unknown Provider.');
163
-        }
164
-
165
-        if (!$providersConfig[$name]['enabled']) {
166
-            throw new UnexpectedValueException('Disabled Provider.');
167
-        }
168
-
169
-        $config = $providersConfig[$name];
170
-        $config += [
171
-            'debug_mode' => $this->config['debug_mode'],
172
-            'debug_file' => $this->config['debug_file'],
173
-        ];
174
-
175
-        if (!isset($config['callback']) && isset($this->config['callback'])) {
176
-            $config['callback'] = $this->config['callback'];
177
-        }
178
-
179
-        return $config;
180
-    }
181
-
182
-    /**
183
-     * Returns a boolean of whether the user is connected with a provider
184
-     *
185
-     * @param string $name adapter's name (case insensitive)
186
-     *
187
-     * @return bool
188
-     * @throws InvalidArgumentException
189
-     * @throws UnexpectedValueException
190
-     */
191
-    public function isConnectedWith($name)
192
-    {
193
-        return $this->getAdapter($name)->isConnected();
194
-    }
195
-
196
-    /**
197
-     * Returns a list of enabled adapters names
198
-     *
199
-     * @return array
200
-     */
201
-    public function getProviders()
202
-    {
203
-        $providers = [];
204
-
205
-        foreach ($this->config['providers'] as $name => $config) {
206
-            if ($config['enabled']) {
207
-                $providers[] = $name;
208
-            }
209
-        }
210
-
211
-        return $providers;
212
-    }
213
-
214
-    /**
215
-     * Returns a list of currently connected adapters names
216
-     *
217
-     * @return array
218
-     * @throws InvalidArgumentException
219
-     * @throws UnexpectedValueException
220
-     */
221
-    public function getConnectedProviders()
222
-    {
223
-        $providers = [];
224
-
225
-        foreach ($this->getProviders() as $name) {
226
-            if ($this->isConnectedWith($name)) {
227
-                $providers[] = $name;
228
-            }
229
-        }
230
-
231
-        return $providers;
232
-    }
233
-
234
-    /**
235
-     * Returns a list of new instances of currently connected adapters
236
-     *
237
-     * @return \Hybridauth\Adapter\AdapterInterface[]
238
-     * @throws InvalidArgumentException
239
-     * @throws UnexpectedValueException
240
-     */
241
-    public function getConnectedAdapters()
242
-    {
243
-        $adapters = [];
244
-
245
-        foreach ($this->getProviders() as $name) {
246
-            $adapter = $this->getAdapter($name);
247
-
248
-            if ($adapter->isConnected()) {
249
-                $adapters[$name] = $adapter;
250
-            }
251
-        }
252
-
253
-        return $adapters;
254
-    }
255
-
256
-    /**
257
-     * Disconnect all currently connected adapters at once
258
-     */
259
-    public function disconnectAllAdapters()
260
-    {
261
-        foreach ($this->getProviders() as $name) {
262
-            $adapter = $this->getAdapter($name);
263
-
264
-            if ($adapter->isConnected()) {
265
-                $adapter->disconnect();
266
-            }
267
-        }
268
-    }
27
+	/**
28
+	 * Hybridauth config.
29
+	 *
30
+	 * @var array
31
+	 */
32
+	protected $config;
33
+
34
+	/**
35
+	 * Storage.
36
+	 *
37
+	 * @var StorageInterface
38
+	 */
39
+	protected $storage;
40
+
41
+	/**
42
+	 * HttpClient.
43
+	 *
44
+	 * @var HttpClientInterface
45
+	 */
46
+	protected $httpClient;
47
+
48
+	/**
49
+	 * Logger.
50
+	 *
51
+	 * @var LoggerInterface
52
+	 */
53
+	protected $logger;
54
+
55
+	/**
56
+	 * @param array|string $config Array with configuration or Path to PHP file that will return array
57
+	 * @param HttpClientInterface $httpClient
58
+	 * @param StorageInterface $storage
59
+	 * @param LoggerInterface $logger
60
+	 *
61
+	 * @throws InvalidArgumentException
62
+	 */
63
+	public function __construct(
64
+		$config,
65
+		HttpClientInterface $httpClient = null,
66
+		StorageInterface $storage = null,
67
+		LoggerInterface $logger = null
68
+	) {
69
+		if (is_string($config) && file_exists($config)) {
70
+			$config = include $config;
71
+		} elseif (!is_array($config)) {
72
+			throw new InvalidArgumentException('Hybridauth config does not exist on the given path.');
73
+		}
74
+
75
+		$this->config = $config + [
76
+				'debug_mode' => Logger::NONE,
77
+				'debug_file' => '',
78
+				'curl_options' => null,
79
+				'providers' => []
80
+			];
81
+		$this->storage = $storage;
82
+		$this->logger = $logger;
83
+		$this->httpClient = $httpClient;
84
+	}
85
+
86
+	/**
87
+	 * Instantiate the given provider and authentication or authorization protocol.
88
+	 *
89
+	 * If not authenticated yet, the user will be redirected to the provider's site for
90
+	 * authentication/authorisation, otherwise it will simply return an instance of
91
+	 * provider's adapter.
92
+	 *
93
+	 * @param string $name adapter's name (case insensitive)
94
+	 *
95
+	 * @return \Hybridauth\Adapter\AdapterInterface
96
+	 * @throws InvalidArgumentException
97
+	 * @throws UnexpectedValueException
98
+	 */
99
+	public function authenticate($name)
100
+	{
101
+		$adapter = $this->getAdapter($name);
102
+
103
+		$adapter->authenticate();
104
+
105
+		return $adapter;
106
+	}
107
+
108
+	/**
109
+	 * Returns a new instance of a provider's adapter by name
110
+	 *
111
+	 * @param string $name adapter's name (case insensitive)
112
+	 *
113
+	 * @return \Hybridauth\Adapter\AdapterInterface
114
+	 * @throws InvalidArgumentException
115
+	 * @throws UnexpectedValueException
116
+	 */
117
+	public function getAdapter($name)
118
+	{
119
+		$config = $this->getProviderConfig($name);
120
+
121
+		$adapter = isset($config['adapter']) ? $config['adapter'] : sprintf('Hybridauth\\Provider\\%s', $name);
122
+
123
+		if (!class_exists($adapter)) {
124
+			$unexistingConfiguredAdapter = $adapter;
125
+			$adapter = null;
126
+			$fs = new \FilesystemIterator(__DIR__ . '/Provider/');
127
+			/** @var \SplFileInfo $file */
128
+			foreach ($fs as $file) {
129
+				if (!$file->isDir()) {
130
+					$provider = strtok($file->getFilename(), '.');
131
+					if (mb_strtolower($name) === mb_strtolower($provider)) {
132
+						$adapter = sprintf('Hybridauth\\Provider\\%s', $provider);
133
+						break;
134
+					}
135
+				}
136
+			}
137
+			if ($adapter === null) {
138
+				throw new InvalidArgumentException("Unknown Provider (name: $name / configured: $unexistingConfiguredAdapter).");
139
+			}
140
+		}
141
+
142
+		return new $adapter($config, $this->httpClient, $this->storage, $this->logger);
143
+	}
144
+
145
+	/**
146
+	 * Get provider config by name.
147
+	 *
148
+	 * @param string $name adapter's name (case insensitive)
149
+	 *
150
+	 * @throws UnexpectedValueException
151
+	 * @throws InvalidArgumentException
152
+	 *
153
+	 * @return array
154
+	 */
155
+	public function getProviderConfig($name)
156
+	{
157
+		$name = strtolower($name);
158
+
159
+		$providersConfig = array_change_key_case($this->config['providers'], CASE_LOWER);
160
+
161
+		if (!isset($providersConfig[$name])) {
162
+			throw new InvalidArgumentException('Unknown Provider.');
163
+		}
164
+
165
+		if (!$providersConfig[$name]['enabled']) {
166
+			throw new UnexpectedValueException('Disabled Provider.');
167
+		}
168
+
169
+		$config = $providersConfig[$name];
170
+		$config += [
171
+			'debug_mode' => $this->config['debug_mode'],
172
+			'debug_file' => $this->config['debug_file'],
173
+		];
174
+
175
+		if (!isset($config['callback']) && isset($this->config['callback'])) {
176
+			$config['callback'] = $this->config['callback'];
177
+		}
178
+
179
+		return $config;
180
+	}
181
+
182
+	/**
183
+	 * Returns a boolean of whether the user is connected with a provider
184
+	 *
185
+	 * @param string $name adapter's name (case insensitive)
186
+	 *
187
+	 * @return bool
188
+	 * @throws InvalidArgumentException
189
+	 * @throws UnexpectedValueException
190
+	 */
191
+	public function isConnectedWith($name)
192
+	{
193
+		return $this->getAdapter($name)->isConnected();
194
+	}
195
+
196
+	/**
197
+	 * Returns a list of enabled adapters names
198
+	 *
199
+	 * @return array
200
+	 */
201
+	public function getProviders()
202
+	{
203
+		$providers = [];
204
+
205
+		foreach ($this->config['providers'] as $name => $config) {
206
+			if ($config['enabled']) {
207
+				$providers[] = $name;
208
+			}
209
+		}
210
+
211
+		return $providers;
212
+	}
213
+
214
+	/**
215
+	 * Returns a list of currently connected adapters names
216
+	 *
217
+	 * @return array
218
+	 * @throws InvalidArgumentException
219
+	 * @throws UnexpectedValueException
220
+	 */
221
+	public function getConnectedProviders()
222
+	{
223
+		$providers = [];
224
+
225
+		foreach ($this->getProviders() as $name) {
226
+			if ($this->isConnectedWith($name)) {
227
+				$providers[] = $name;
228
+			}
229
+		}
230
+
231
+		return $providers;
232
+	}
233
+
234
+	/**
235
+	 * Returns a list of new instances of currently connected adapters
236
+	 *
237
+	 * @return \Hybridauth\Adapter\AdapterInterface[]
238
+	 * @throws InvalidArgumentException
239
+	 * @throws UnexpectedValueException
240
+	 */
241
+	public function getConnectedAdapters()
242
+	{
243
+		$adapters = [];
244
+
245
+		foreach ($this->getProviders() as $name) {
246
+			$adapter = $this->getAdapter($name);
247
+
248
+			if ($adapter->isConnected()) {
249
+				$adapters[$name] = $adapter;
250
+			}
251
+		}
252
+
253
+		return $adapters;
254
+	}
255
+
256
+	/**
257
+	 * Disconnect all currently connected adapters at once
258
+	 */
259
+	public function disconnectAllAdapters()
260
+	{
261
+		foreach ($this->getProviders() as $name) {
262
+			$adapter = $this->getAdapter($name);
263
+
264
+			if ($adapter->isConnected()) {
265
+				$adapter->disconnect();
266
+			}
267
+		}
268
+	}
269 269
 }
Please login to merge, or discard this patch.
Spacing   +7 added lines, -7 removed lines patch added patch discarded remove patch
@@ -68,7 +68,7 @@  discard block
 block discarded – undo
68 68
     ) {
69 69
         if (is_string($config) && file_exists($config)) {
70 70
             $config = include $config;
71
-        } elseif (!is_array($config)) {
71
+        } elseif ( ! is_array($config)) {
72 72
             throw new InvalidArgumentException('Hybridauth config does not exist on the given path.');
73 73
         }
74 74
 
@@ -120,13 +120,13 @@  discard block
 block discarded – undo
120 120
 
121 121
         $adapter = isset($config['adapter']) ? $config['adapter'] : sprintf('Hybridauth\\Provider\\%s', $name);
122 122
 
123
-        if (!class_exists($adapter)) {
123
+        if ( ! class_exists($adapter)) {
124 124
             $unexistingConfiguredAdapter = $adapter;
125 125
             $adapter = null;
126
-            $fs = new \FilesystemIterator(__DIR__ . '/Provider/');
126
+            $fs = new \FilesystemIterator(__DIR__.'/Provider/');
127 127
             /** @var \SplFileInfo $file */
128 128
             foreach ($fs as $file) {
129
-                if (!$file->isDir()) {
129
+                if ( ! $file->isDir()) {
130 130
                     $provider = strtok($file->getFilename(), '.');
131 131
                     if (mb_strtolower($name) === mb_strtolower($provider)) {
132 132
                         $adapter = sprintf('Hybridauth\\Provider\\%s', $provider);
@@ -158,11 +158,11 @@  discard block
 block discarded – undo
158 158
 
159 159
         $providersConfig = array_change_key_case($this->config['providers'], CASE_LOWER);
160 160
 
161
-        if (!isset($providersConfig[$name])) {
161
+        if ( ! isset($providersConfig[$name])) {
162 162
             throw new InvalidArgumentException('Unknown Provider.');
163 163
         }
164 164
 
165
-        if (!$providersConfig[$name]['enabled']) {
165
+        if ( ! $providersConfig[$name]['enabled']) {
166 166
             throw new UnexpectedValueException('Disabled Provider.');
167 167
         }
168 168
 
@@ -172,7 +172,7 @@  discard block
 block discarded – undo
172 172
             'debug_file' => $this->config['debug_file'],
173 173
         ];
174 174
 
175
-        if (!isset($config['callback']) && isset($this->config['callback'])) {
175
+        if ( ! isset($config['callback']) && isset($this->config['callback'])) {
176 176
             $config['callback'] = $this->config['callback'];
177 177
         }
178 178
 
Please login to merge, or discard this patch.