diff --git a/src/Provider/Facebook.php b/src/Provider/Facebook.php index f2e6bb1..9155836 100644 --- a/src/Provider/Facebook.php +++ b/src/Provider/Facebook.php @@ -6,43 +6,71 @@ use League\OAuth2\Client\Entity\User; class Facebook extends AbstractProvider { - public $scopes = ['offline_access', 'email', 'read_stream']; + /** + * @const string The fallback Graph API version to use for requests. + */ + const DEFAULT_GRAPH_VERSION = 'v2.2'; + + /** + * @var string The Graph API version to use for requests. + */ + protected $graphApiVersion; + + public $scopes = ['public_profile', 'email']; + public $responseType = 'string'; + public function __construct($options) + { + parent::__construct($options); + $this->graphApiVersion = (isset($options['graphApiVersion'])) + ? $options['graphApiVersion'] + : static::DEFAULT_GRAPH_VERSION; + } + public function urlAuthorize() { - return 'https://www.facebook.com/dialog/oauth'; + return 'https://www.facebook.com/'.$this->graphApiVersion.'/dialog/oauth'; } public function urlAccessToken() { - return 'https://graph.facebook.com/oauth/access_token'; + return 'https://graph.facebook.com/'.$this->graphApiVersion.'/oauth/access_token'; } public function urlUserDetails(\League\OAuth2\Client\Token\AccessToken $token) { - return 'https://graph.facebook.com/me?access_token='.$token; + $fields = implode(',', [ + 'id', + 'name', + 'first_name', + 'last_name', + 'email', + 'hometown', + 'bio', + 'picture.type(large){url}', + 'gender', + 'locale', + 'link', + ]); + + return 'https://graph.facebook.com/'.$this->graphApiVersion.'/me?fields='.$fields.'&access_token='.$token; } public function userDetails($response, \League\OAuth2\Client\Token\AccessToken $token) { - $client = $this->getHttpClient(); - $client->setBaseUrl('https://graph.facebook.com/me/picture?type=normal&access_token='.$token->accessToken); - $request = $client->get()->send(); - $info = $request->getInfo(); - $imageUrl = $info['url']; - $user = new User(); - $username = (isset($response->username)) ? $response->username : null; $email = (isset($response->email)) ? $response->email : null; + // The "hometown" field will only be returned if you ask for the `user_hometown` permission. $location = (isset($response->hometown->name)) ? $response->hometown->name : null; $description = (isset($response->bio)) ? $response->bio : null; - $imageUrl = ($imageUrl) ?: null; + $imageUrl = (isset($response->picture->data->url)) ? $response->picture->data->url : null; + $gender = (isset($response->gender)) ? $response->gender : null; + $locale = (isset($response->locale)) ? $response->locale : null; $user->exchangeArray([ 'uid' => $response->id, - 'nickname' => $username, 'name' => $response->name, 'firstname' => $response->first_name, 'lastname' => $response->last_name, @@ -50,6 +78,8 @@ class Facebook extends AbstractProvider 'location' => $location, 'description' => $description, 'imageurl' => $imageUrl, + 'gender' => $gender, + 'locale' => $locale, 'urls' => [ 'Facebook' => $response->link ], ]); diff --git a/test/src/Provider/FacebookTest.php b/test/src/Provider/FacebookTest.php index 9a0c7d2..8e6814d 100644 --- a/test/src/Provider/FacebookTest.php +++ b/test/src/Provider/FacebookTest.php @@ -6,6 +6,9 @@ use Mockery as m; class FacebookTest extends \PHPUnit_Framework_TestCase { + /** + * @var \League\OAuth2\Client\Provider\Facebook + */ protected $provider; protected function setUp() @@ -42,8 +45,40 @@ class FacebookTest extends \PHPUnit_Framework_TestCase { $url = $this->provider->urlAccessToken(); $uri = parse_url($url); + $graphVersion = \League\OAuth2\Client\Provider\Facebook::DEFAULT_GRAPH_VERSION; - $this->assertEquals('/oauth/access_token', $uri['path']); + $this->assertEquals('/'.$graphVersion.'/oauth/access_token', $uri['path']); + } + + public function testGraphApiVersionCanBeCustomized() + { + $graphVersion = 'v13.37'; + $provider = new \League\OAuth2\Client\Provider\Facebook([ + 'graphApiVersion' => $graphVersion, + ]); + $fooToken = new \League\OAuth2\Client\Token\AccessToken(['access_token' => 'foo_token']); + + $urlAuthorize = $provider->urlAuthorize(); + $urlAccessToken = $provider->urlAccessToken(); + $urlUserDetails = parse_url($provider->urlUserDetails($fooToken), PHP_URL_PATH); + + $this->assertEquals('https://www.facebook.com/'.$graphVersion.'/dialog/oauth', $urlAuthorize); + $this->assertEquals('https://graph.facebook.com/'.$graphVersion.'/oauth/access_token', $urlAccessToken); + $this->assertEquals('/'.$graphVersion.'/me', $urlUserDetails); + } + + public function testGraphApiVersionWillFallbackToDefault() + { + $graphVersion = \League\OAuth2\Client\Provider\Facebook::DEFAULT_GRAPH_VERSION; + $fooToken = new \League\OAuth2\Client\Token\AccessToken(['access_token' => 'foo_token']); + + $urlAuthorize = $this->provider->urlAuthorize(); + $urlAccessToken = $this->provider->urlAccessToken(); + $urlUserDetails = parse_url($this->provider->urlUserDetails($fooToken), PHP_URL_PATH); + + $this->assertEquals('https://www.facebook.com/'.$graphVersion.'/dialog/oauth', $urlAuthorize); + $this->assertEquals('https://graph.facebook.com/'.$graphVersion.'/oauth/access_token', $urlAccessToken); + $this->assertEquals('/'.$graphVersion.'/me', $urlUserDetails); } public function testGetAccessToken() @@ -58,8 +93,6 @@ class FacebookTest extends \PHPUnit_Framework_TestCase $token = $this->provider->getAccessToken('authorization_code', ['code' => 'mock_authorization_code']); -# print_r($token);die(); - $this->assertEquals('mock_access_token', $token->accessToken); $this->assertLessThanOrEqual(time() + 3600, $token->expires); $this->assertGreaterThanOrEqual(time(), $token->expires); @@ -69,7 +102,7 @@ class FacebookTest extends \PHPUnit_Framework_TestCase public function testScopes() { - $this->assertEquals(['offline_access', 'email', 'read_stream'], $this->provider->getScopes()); + $this->assertEquals(['public_profile', 'email'], $this->provider->getScopes()); } public function testUserData() @@ -82,7 +115,7 @@ class FacebookTest extends \PHPUnit_Framework_TestCase $getResponse->shouldReceive('getInfo')->andReturn(['url' => 'mock_image_url']); $client = m::mock('Guzzle\Service\Client'); - $client->shouldReceive('setBaseUrl')->times(6); + $client->shouldReceive('setBaseUrl')->times(5); $client->shouldReceive('post->send')->times(1)->andReturn($postResponse); $client->shouldReceive('get->send')->andReturn($getResponse); $this->provider->setHttpClient($client);