Skip to content

Commit

Permalink
Fix LinkedInProvider for new API
Browse files Browse the repository at this point in the history
LinkedIn has suddenly stopped supported the previous endpoint we used to retrieve user profile information so we need to use the new API for authenticating users.

Fixes #309
  • Loading branch information
driesvints committed Dec 18, 2018
1 parent 049c6ba commit 001fcfa
Showing 1 changed file with 48 additions and 31 deletions.
79 changes: 48 additions & 31 deletions src/Two/LinkedInProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class LinkedInProvider extends AbstractProvider implements ProviderInterface
*
* @var array
*/
protected $scopes = ['r_basicprofile', 'r_emailaddress'];
protected $scopes = ['r_liteprofile', 'r_emailaddress'];

/**
* The separating character for the requested scopes.
Expand All @@ -20,17 +20,6 @@ class LinkedInProvider extends AbstractProvider implements ProviderInterface
*/
protected $scopeSeparator = ' ';

/**
* The fields that are included in the profile.
*
* @var array
*/
protected $fields = [
'id', 'first-name', 'last-name', 'formatted-name',
'email-address', 'headline', 'location', 'industry',
'public-profile-url', 'picture-url', 'picture-urls::(original)',
];

/**
* {@inheritdoc}
*/
Expand Down Expand Up @@ -63,45 +52,73 @@ protected function getTokenFields($code)
*/
protected function getUserByToken($token)
{
$fields = implode(',', $this->fields);
$basicProfile = $this->getBasicProfile($token);
$emailAddress = $this->getEmailAddress($token);

$url = 'https://api.linkedin.com/v1/people/~:('.$fields.')';
return array_merge($basicProfile, $emailAddress);
}

/**
* Get the basic profile fields for the user.
*
* @param string $token
* @return array
*/
protected function getBasicProfile($token)
{
$url = 'https://api.linkedin.com/v2/me?projection=(id,firstName,lastName,profilePicture(displayImage~:playableStreams))';

$response = $this->getHttpClient()->get($url, [
'headers' => [
'x-li-format' => 'json',
'Authorization' => 'Bearer '.$token,
'X-RestLi-Protocol-Version' => '2.0.0',
],
]);

return json_decode($response->getBody(), true);
}

/**
* {@inheritdoc}
* Get the email address for the user.
*
* @param string $token
* @return array
*/
protected function mapUserToObject(array $user)
protected function getEmailAddress($token)
{
return (new User)->setRaw($user)->map([
'id' => $user['id'],
'nickname' => null,
'name' => Arr::get($user, 'formattedName'),
'email' => Arr::get($user, 'emailAddress'),
'avatar' => Arr::get($user, 'pictureUrl'),
'avatar_original' => Arr::get($user, 'pictureUrls.values.0'),
$url = 'https://api.linkedin.com/v2/emailAddress?q=members&projection=(elements*(handle~))';

$response = $this->getHttpClient()->get($url, [
'headers' => [
'Authorization' => 'Bearer '.$token,
'X-RestLi-Protocol-Version' => '2.0.0',
],
]);

return json_decode($response->getBody(), true)['elements'][0]['handle~'];
}

/**
* Set the user fields to request from LinkedIn.
*
* @param array $fields
* @return $this
* {@inheritdoc}
*/
public function fields(array $fields)
protected function mapUserToObject(array $user)
{
$this->fields = $fields;
$name = Arr::get($user, 'firstName.localized.en_US').' '.Arr::get($user, 'lastName.localized.en_US');
$images = Arr::get($user, 'profilePicture.displayImage~.elements');
$avatar = Arr::first(Arr::where($images, function ($image) {
return $image['data']['com.linkedin.digitalmedia.mediaartifact.StillImage']['storageSize']['width'] === 100;
}));
$originalAvatar = Arr::first(Arr::where($images, function ($image) {
return $image['data']['com.linkedin.digitalmedia.mediaartifact.StillImage']['storageSize']['width'] === 800;
}));

return $this;
return (new User)->setRaw($user)->map([
'id' => $user['id'],
'nickname' => null,
'name' => $name,
'email' => Arr::get($user, 'emailAddress'),
'avatar' => Arr::get($avatar, 'identifiers.0.identifier'),
'avatar_original' => Arr::get($originalAvatar, 'identifiers.0.identifier'),
]);
}
}

0 comments on commit 001fcfa

Please sign in to comment.