106 changed files with 11685 additions and 222 deletions
@ -0,0 +1,160 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Authentication; |
|||
|
|||
/** |
|||
* Class AccessToken |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class AccessToken |
|||
{ |
|||
/** |
|||
* The access token value. |
|||
* |
|||
* @var string |
|||
*/ |
|||
protected $value = ''; |
|||
|
|||
/** |
|||
* Date when token expires. |
|||
* |
|||
* @var \DateTime|null |
|||
*/ |
|||
protected $expiresAt; |
|||
|
|||
/** |
|||
* Create a new access token entity. |
|||
* |
|||
* @param string $accessToken |
|||
* @param int $expiresAt |
|||
*/ |
|||
public function __construct($accessToken, $expiresAt = 0) |
|||
{ |
|||
$this->value = $accessToken; |
|||
if ($expiresAt) { |
|||
$this->setExpiresAtFromTimeStamp($expiresAt); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Generate an app secret proof to sign a request to Graph. |
|||
* |
|||
* @param string $appSecret The app secret. |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getAppSecretProof($appSecret) |
|||
{ |
|||
return hash_hmac('sha256', $this->value, $appSecret); |
|||
} |
|||
|
|||
/** |
|||
* Getter for expiresAt. |
|||
* |
|||
* @return \DateTime|null |
|||
*/ |
|||
public function getExpiresAt() |
|||
{ |
|||
return $this->expiresAt; |
|||
} |
|||
|
|||
/** |
|||
* Determines whether or not this is an app access token. |
|||
* |
|||
* @return bool |
|||
*/ |
|||
public function isAppAccessToken() |
|||
{ |
|||
return strpos($this->value, '|') !== false; |
|||
} |
|||
|
|||
/** |
|||
* Determines whether or not this is a long-lived token. |
|||
* |
|||
* @return bool |
|||
*/ |
|||
public function isLongLived() |
|||
{ |
|||
if ($this->expiresAt) { |
|||
return $this->expiresAt->getTimestamp() > time() + (60 * 60 * 2); |
|||
} |
|||
|
|||
if ($this->isAppAccessToken()) { |
|||
return true; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
/** |
|||
* Checks the expiration of the access token. |
|||
* |
|||
* @return boolean|null |
|||
*/ |
|||
public function isExpired() |
|||
{ |
|||
if ($this->getExpiresAt() instanceof \DateTime) { |
|||
return $this->getExpiresAt()->getTimestamp() < time(); |
|||
} |
|||
|
|||
if ($this->isAppAccessToken()) { |
|||
return false; |
|||
} |
|||
|
|||
return null; |
|||
} |
|||
|
|||
/** |
|||
* Returns the access token as a string. |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getValue() |
|||
{ |
|||
return $this->value; |
|||
} |
|||
|
|||
/** |
|||
* Returns the access token as a string. |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function __toString() |
|||
{ |
|||
return $this->getValue(); |
|||
} |
|||
|
|||
/** |
|||
* Setter for expires_at. |
|||
* |
|||
* @param int $timeStamp |
|||
*/ |
|||
protected function setExpiresAtFromTimeStamp($timeStamp) |
|||
{ |
|||
$dt = new \DateTime(); |
|||
$dt->setTimestamp($timeStamp); |
|||
$this->expiresAt = $dt; |
|||
} |
|||
} |
@ -0,0 +1,390 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Authentication; |
|||
|
|||
use Facebook\Exceptions\FacebookSDKException; |
|||
|
|||
/** |
|||
* Class AccessTokenMetadata |
|||
* |
|||
* Represents metadata from an access token. |
|||
* |
|||
* @package Facebook |
|||
* @see https://developers.facebook.com/docs/graph-api/reference/debug_token |
|||
*/ |
|||
class AccessTokenMetadata |
|||
{ |
|||
/** |
|||
* The access token metadata. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected $metadata = []; |
|||
|
|||
/** |
|||
* Properties that should be cast as DateTime objects. |
|||
* |
|||
* @var array |
|||
*/ |
|||
protected static $dateProperties = ['expires_at', 'issued_at']; |
|||
|
|||
/** |
|||
* @param array $metadata |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function __construct(array $metadata) |
|||
{ |
|||
if (!isset($metadata['data'])) { |
|||
throw new FacebookSDKException('Unexpected debug token response data.', 401); |
|||
} |
|||
|
|||
$this->metadata = $metadata['data']; |
|||
|
|||
$this->castTimestampsToDateTime(); |
|||
} |
|||
|
|||
/** |
|||
* Returns a value from the metadata. |
|||
* |
|||
* @param string $field The property to retrieve. |
|||
* @param mixed $default The default to return if the property doesn't exist. |
|||
* |
|||
* @return mixed |
|||
*/ |
|||
public function getField($field, $default = null) |
|||
{ |
|||
if (isset($this->metadata[$field])) { |
|||
return $this->metadata[$field]; |
|||
} |
|||
|
|||
return $default; |
|||
} |
|||
|
|||
/** |
|||
* Returns a value from the metadata. |
|||
* |
|||
* @param string $field The property to retrieve. |
|||
* @param mixed $default The default to return if the property doesn't exist. |
|||
* |
|||
* @return mixed |
|||
* |
|||
* @deprecated 5.0.0 getProperty() has been renamed to getField() |
|||
* @todo v6: Remove this method |
|||
*/ |
|||
public function getProperty($field, $default = null) |
|||
{ |
|||
return $this->getField($field, $default); |
|||
} |
|||
|
|||
/** |
|||
* Returns a value from a child property in the metadata. |
|||
* |
|||
* @param string $parentField The parent property. |
|||
* @param string $field The property to retrieve. |
|||
* @param mixed $default The default to return if the property doesn't exist. |
|||
* |
|||
* @return mixed |
|||
*/ |
|||
public function getChildProperty($parentField, $field, $default = null) |
|||
{ |
|||
if (!isset($this->metadata[$parentField])) { |
|||
return $default; |
|||
} |
|||
|
|||
if (!isset($this->metadata[$parentField][$field])) { |
|||
return $default; |
|||
} |
|||
|
|||
return $this->metadata[$parentField][$field]; |
|||
} |
|||
|
|||
/** |
|||
* Returns a value from the error metadata. |
|||
* |
|||
* @param string $field The property to retrieve. |
|||
* @param mixed $default The default to return if the property doesn't exist. |
|||
* |
|||
* @return mixed |
|||
*/ |
|||
public function getErrorProperty($field, $default = null) |
|||
{ |
|||
return $this->getChildProperty('error', $field, $default); |
|||
} |
|||
|
|||
/** |
|||
* Returns a value from the "metadata" metadata. *Brain explodes* |
|||
* |
|||
* @param string $field The property to retrieve. |
|||
* @param mixed $default The default to return if the property doesn't exist. |
|||
* |
|||
* @return mixed |
|||
*/ |
|||
public function getMetadataProperty($field, $default = null) |
|||
{ |
|||
return $this->getChildProperty('metadata', $field, $default); |
|||
} |
|||
|
|||
/** |
|||
* The ID of the application this access token is for. |
|||
* |
|||
* @return string|null |
|||
*/ |
|||
public function getAppId() |
|||
{ |
|||
return $this->getField('app_id'); |
|||
} |
|||
|
|||
/** |
|||
* Name of the application this access token is for. |
|||
* |
|||
* @return string|null |
|||
*/ |
|||
public function getApplication() |
|||
{ |
|||
return $this->getField('application'); |
|||
} |
|||
|
|||
/** |
|||
* Any error that a request to the graph api |
|||
* would return due to the access token. |
|||
* |
|||
* @return bool|null |
|||
*/ |
|||
public function isError() |
|||
{ |
|||
return $this->getField('error') !== null; |
|||
} |
|||
|
|||
/** |
|||
* The error code for the error. |
|||
* |
|||
* @return int|null |
|||
*/ |
|||
public function getErrorCode() |
|||
{ |
|||
return $this->getErrorProperty('code'); |
|||
} |
|||
|
|||
/** |
|||
* The error message for the error. |
|||
* |
|||
* @return string|null |
|||
*/ |
|||
public function getErrorMessage() |
|||
{ |
|||
return $this->getErrorProperty('message'); |
|||
} |
|||
|
|||
/** |
|||
* The error subcode for the error. |
|||
* |
|||
* @return int|null |
|||
*/ |
|||
public function getErrorSubcode() |
|||
{ |
|||
return $this->getErrorProperty('subcode'); |
|||
} |
|||
|
|||
/** |
|||
* DateTime when this access token expires. |
|||
* |
|||
* @return \DateTime|null |
|||
*/ |
|||
public function getExpiresAt() |
|||
{ |
|||
return $this->getField('expires_at'); |
|||
} |
|||
|
|||
/** |
|||
* Whether the access token is still valid or not. |
|||
* |
|||
* @return boolean|null |
|||
*/ |
|||
public function getIsValid() |
|||
{ |
|||
return $this->getField('is_valid'); |
|||
} |
|||
|
|||
/** |
|||
* DateTime when this access token was issued. |
|||
* |
|||
* Note that the issued_at field is not returned |
|||
* for short-lived access tokens. |
|||
* |
|||
* @see https://developers.facebook.com/docs/facebook-login/access-tokens#debug |
|||
* |
|||
* @return \DateTime|null |
|||
*/ |
|||
public function getIssuedAt() |
|||
{ |
|||
return $this->getField('issued_at'); |
|||
} |
|||
|
|||
/** |
|||
* General metadata associated with the access token. |
|||
* Can contain data like 'sso', 'auth_type', 'auth_nonce'. |
|||
* |
|||
* @return array|null |
|||
*/ |
|||
public function getMetadata() |
|||
{ |
|||
return $this->getField('metadata'); |
|||
} |
|||
|
|||
/** |
|||
* The 'sso' child property from the 'metadata' parent property. |
|||
* |
|||
* @return string|null |
|||
*/ |
|||
public function getSso() |
|||
{ |
|||
return $this->getMetadataProperty('sso'); |
|||
} |
|||
|
|||
/** |
|||
* The 'auth_type' child property from the 'metadata' parent property. |
|||
* |
|||
* @return string|null |
|||
*/ |
|||
public function getAuthType() |
|||
{ |
|||
return $this->getMetadataProperty('auth_type'); |
|||
} |
|||
|
|||
/** |
|||
* The 'auth_nonce' child property from the 'metadata' parent property. |
|||
* |
|||
* @return string|null |
|||
*/ |
|||
public function getAuthNonce() |
|||
{ |
|||
return $this->getMetadataProperty('auth_nonce'); |
|||
} |
|||
|
|||
/** |
|||
* For impersonated access tokens, the ID of |
|||
* the page this token contains. |
|||
* |
|||
* @return string|null |
|||
*/ |
|||
public function getProfileId() |
|||
{ |
|||
return $this->getField('profile_id'); |
|||
} |
|||
|
|||
/** |
|||
* List of permissions that the user has granted for |
|||
* the app in this access token. |
|||
* |
|||
* @return array |
|||
*/ |
|||
public function getScopes() |
|||
{ |
|||
return $this->getField('scopes'); |
|||
} |
|||
|
|||
/** |
|||
* The ID of the user this access token is for. |
|||
* |
|||
* @return string|null |
|||
*/ |
|||
public function getUserId() |
|||
{ |
|||
return $this->getField('user_id'); |
|||
} |
|||
|
|||
/** |
|||
* Ensures the app ID from the access token |
|||
* metadata is what we expect. |
|||
* |
|||
* @param string $appId |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function validateAppId($appId) |
|||
{ |
|||
if ($this->getAppId() !== $appId) { |
|||
throw new FacebookSDKException('Access token metadata contains unexpected app ID.', 401); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Ensures the user ID from the access token |
|||
* metadata is what we expect. |
|||
* |
|||
* @param string $userId |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function validateUserId($userId) |
|||
{ |
|||
if ($this->getUserId() !== $userId) { |
|||
throw new FacebookSDKException('Access token metadata contains unexpected user ID.', 401); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Ensures the access token has not expired yet. |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function validateExpiration() |
|||
{ |
|||
if (!$this->getExpiresAt() instanceof \DateTime) { |
|||
return; |
|||
} |
|||
|
|||
if ($this->getExpiresAt()->getTimestamp() < time()) { |
|||
throw new FacebookSDKException('Inspection of access token metadata shows that the access token has expired.', 401); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Converts a unix timestamp into a DateTime entity. |
|||
* |
|||
* @param int $timestamp |
|||
* |
|||
* @return \DateTime |
|||
*/ |
|||
private function convertTimestampToDateTime($timestamp) |
|||
{ |
|||
$dt = new \DateTime(); |
|||
$dt->setTimestamp($timestamp); |
|||
|
|||
return $dt; |
|||
} |
|||
|
|||
/** |
|||
* Casts the unix timestamps as DateTime entities. |
|||
*/ |
|||
private function castTimestampsToDateTime() |
|||
{ |
|||
foreach (static::$dateProperties as $key) { |
|||
if (isset($this->metadata[$key])) { |
|||
$this->metadata[$key] = $this->convertTimestampToDateTime($this->metadata[$key]); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,292 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Authentication; |
|||
|
|||
use Facebook\Facebook; |
|||
use Facebook\FacebookApp; |
|||
use Facebook\FacebookRequest; |
|||
use Facebook\FacebookResponse; |
|||
use Facebook\FacebookClient; |
|||
use Facebook\Exceptions\FacebookResponseException; |
|||
use Facebook\Exceptions\FacebookSDKException; |
|||
|
|||
/** |
|||
* Class OAuth2Client |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class OAuth2Client |
|||
{ |
|||
/** |
|||
* @const string The base authorization URL. |
|||
*/ |
|||
const BASE_AUTHORIZATION_URL = 'https://www.facebook.com'; |
|||
|
|||
/** |
|||
* The FacebookApp entity. |
|||
* |
|||
* @var FacebookApp |
|||
*/ |
|||
protected $app; |
|||
|
|||
/** |
|||
* The Facebook client. |
|||
* |
|||
* @var FacebookClient |
|||
*/ |
|||
protected $client; |
|||
|
|||
/** |
|||
* The version of the Graph API to use. |
|||
* |
|||
* @var string |
|||
*/ |
|||
protected $graphVersion; |
|||
|
|||
/** |
|||
* The last request sent to Graph. |
|||
* |
|||
* @var FacebookRequest|null |
|||
*/ |
|||
protected $lastRequest; |
|||
|
|||
/** |
|||
* @param FacebookApp $app |
|||
* @param FacebookClient $client |
|||
* @param string|null $graphVersion The version of the Graph API to use. |
|||
*/ |
|||
public function __construct(FacebookApp $app, FacebookClient $client, $graphVersion = null) |
|||
{ |
|||
$this->app = $app; |
|||
$this->client = $client; |
|||
$this->graphVersion = $graphVersion ?: Facebook::DEFAULT_GRAPH_VERSION; |
|||
} |
|||
|
|||
/** |
|||
* Returns the last FacebookRequest that was sent. |
|||
* Useful for debugging and testing. |
|||
* |
|||
* @return FacebookRequest|null |
|||
*/ |
|||
public function getLastRequest() |
|||
{ |
|||
return $this->lastRequest; |
|||
} |
|||
|
|||
/** |
|||
* Get the metadata associated with the access token. |
|||
* |
|||
* @param AccessToken|string $accessToken The access token to debug. |
|||
* |
|||
* @return AccessTokenMetadata |
|||
*/ |
|||
public function debugToken($accessToken) |
|||
{ |
|||
$accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken; |
|||
$params = ['input_token' => $accessToken]; |
|||
|
|||
$this->lastRequest = new FacebookRequest( |
|||
$this->app, |
|||
$this->app->getAccessToken(), |
|||
'GET', |
|||
'/debug_token', |
|||
$params, |
|||
null, |
|||
$this->graphVersion |
|||
); |
|||
$response = $this->client->sendRequest($this->lastRequest); |
|||
$metadata = $response->getDecodedBody(); |
|||
|
|||
return new AccessTokenMetadata($metadata); |
|||
} |
|||
|
|||
/** |
|||
* Generates an authorization URL to begin the process of authenticating a user. |
|||
* |
|||
* @param string $redirectUrl The callback URL to redirect to. |
|||
* @param array $scope An array of permissions to request. |
|||
* @param string $state The CSPRNG-generated CSRF value. |
|||
* @param array $params An array of parameters to generate URL. |
|||
* @param string $separator The separator to use in http_build_query(). |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getAuthorizationUrl($redirectUrl, $state, array $scope = [], array $params = [], $separator = '&') |
|||
{ |
|||
$params += [ |
|||
'client_id' => $this->app->getId(), |
|||
'state' => $state, |
|||
'response_type' => 'code', |
|||
'sdk' => 'php-sdk-' . Facebook::VERSION, |
|||
'redirect_uri' => $redirectUrl, |
|||
'scope' => implode(',', $scope) |
|||
]; |
|||
|
|||
return static::BASE_AUTHORIZATION_URL . '/' . $this->graphVersion . '/dialog/oauth?' . http_build_query($params, null, $separator); |
|||
} |
|||
|
|||
/** |
|||
* Get a valid access token from a code. |
|||
* |
|||
* @param string $code |
|||
* @param string $redirectUri |
|||
* |
|||
* @return AccessToken |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function getAccessTokenFromCode($code, $redirectUri = '') |
|||
{ |
|||
$params = [ |
|||
'code' => $code, |
|||
'redirect_uri' => $redirectUri, |
|||
]; |
|||
|
|||
return $this->requestAnAccessToken($params); |
|||
} |
|||
|
|||
/** |
|||
* Exchanges a short-lived access token with a long-lived access token. |
|||
* |
|||
* @param AccessToken|string $accessToken |
|||
* |
|||
* @return AccessToken |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function getLongLivedAccessToken($accessToken) |
|||
{ |
|||
$accessToken = $accessToken instanceof AccessToken ? $accessToken->getValue() : $accessToken; |
|||
$params = [ |
|||
'grant_type' => 'fb_exchange_token', |
|||
'fb_exchange_token' => $accessToken, |
|||
]; |
|||
|
|||
return $this->requestAnAccessToken($params); |
|||
} |
|||
|
|||
/** |
|||
* Get a valid code from an access token. |
|||
* |
|||
* @param AccessToken|string $accessToken |
|||
* @param string $redirectUri |
|||
* |
|||
* @return AccessToken |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function getCodeFromLongLivedAccessToken($accessToken, $redirectUri = '') |
|||
{ |
|||
$params = [ |
|||
'redirect_uri' => $redirectUri, |
|||
]; |
|||
|
|||
$response = $this->sendRequestWithClientParams('/oauth/client_code', $params, $accessToken); |
|||
$data = $response->getDecodedBody(); |
|||
|
|||
if (!isset($data['code'])) { |
|||
throw new FacebookSDKException('Code was not returned from Graph.', 401); |
|||
} |
|||
|
|||
return $data['code']; |
|||
} |
|||
|
|||
/** |
|||
* Send a request to the OAuth endpoint. |
|||
* |
|||
* @param array $params |
|||
* |
|||
* @return AccessToken |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
protected function requestAnAccessToken(array $params) |
|||
{ |
|||
$response = $this->sendRequestWithClientParams('/oauth/access_token', $params); |
|||
$data = $response->getDecodedBody(); |
|||
|
|||
if (!isset($data['access_token'])) { |
|||
throw new FacebookSDKException('Access token was not returned from Graph.', 401); |
|||
} |
|||
|
|||
// Graph returns two different key names for expiration time |
|||
// on the same endpoint. Doh! :/ |
|||
$expiresAt = 0; |
|||
if (isset($data['expires'])) { |
|||
// For exchanging a short lived token with a long lived token. |
|||
// The expiration time in seconds will be returned as "expires". |
|||
$expiresAt = time() + $data['expires']; |
|||
} elseif (isset($data['expires_in'])) { |
|||
// For exchanging a code for a short lived access token. |
|||
// The expiration time in seconds will be returned as "expires_in". |
|||
// See: https://developers.facebook.com/docs/facebook-login/access-tokens#long-via-code |
|||
$expiresAt = time() + $data['expires_in']; |
|||
} |
|||
|
|||
return new AccessToken($data['access_token'], $expiresAt); |
|||
} |
|||
|
|||
/** |
|||
* Send a request to Graph with an app access token. |
|||
* |
|||
* @param string $endpoint |
|||
* @param array $params |
|||
* @param string|null $accessToken |
|||
* |
|||
* @return FacebookResponse |
|||
* |
|||
* @throws FacebookResponseException |
|||
*/ |
|||
protected function sendRequestWithClientParams($endpoint, array $params, $accessToken = null) |
|||
{ |
|||
$params += $this->getClientParams(); |
|||
|
|||
$accessToken = $accessToken ?: $this->app->getAccessToken(); |
|||
|
|||
$this->lastRequest = new FacebookRequest( |
|||
$this->app, |
|||
$accessToken, |
|||
'GET', |
|||
$endpoint, |
|||
$params, |
|||
null, |
|||
$this->graphVersion |
|||
); |
|||
|
|||
return $this->client->sendRequest($this->lastRequest); |
|||
} |
|||
|
|||
/** |
|||
* Returns the client_* params for OAuth requests. |
|||
* |
|||
* @return array |
|||
*/ |
|||
protected function getClientParams() |
|||
{ |
|||
return [ |
|||
'client_id' => $this->app->getId(), |
|||
'client_secret' => $this->app->getSecret(), |
|||
]; |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Exceptions; |
|||
|
|||
/** |
|||
* Class FacebookAuthenticationException |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class FacebookAuthenticationException extends FacebookSDKException |
|||
{ |
|||
} |
@ -0,0 +1,33 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Exceptions; |
|||
|
|||
/** |
|||
* Class FacebookAuthorizationException |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class FacebookAuthorizationException extends FacebookSDKException |
|||
{ |
|||
} |
@ -0,0 +1,33 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Exceptions; |
|||
|
|||
/** |
|||
* Class FacebookClientException |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class FacebookClientException extends FacebookSDKException |
|||
{ |
|||
} |
@ -0,0 +1,33 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Exceptions; |
|||
|
|||
/** |
|||
* Class FacebookOtherException |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class FacebookOtherException extends FacebookSDKException |
|||
{ |
|||
} |
@ -0,0 +1,208 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Exceptions; |
|||
|
|||
use Facebook\FacebookResponse; |
|||
|
|||
/** |
|||
* Class FacebookResponseException |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class FacebookResponseException extends FacebookSDKException |
|||
{ |
|||
/** |
|||
* @var FacebookResponse The response that threw the exception. |
|||
*/ |
|||
protected $response; |
|||
|
|||
/** |
|||
* @var array Decoded response. |
|||
*/ |
|||
protected $responseData; |
|||
|
|||
/** |
|||
* Creates a FacebookResponseException. |
|||
* |
|||
* @param FacebookResponse $response The response that threw the exception. |
|||
* @param FacebookSDKException $previousException The more detailed exception. |
|||
*/ |
|||
public function __construct(FacebookResponse $response, FacebookSDKException $previousException = null) |
|||
{ |
|||
$this->response = $response; |
|||
$this->responseData = $response->getDecodedBody(); |
|||
|
|||
$errorMessage = $this->get('message', 'Unknown error from Graph.'); |
|||
$errorCode = $this->get('code', -1); |
|||
|
|||
parent::__construct($errorMessage, $errorCode, $previousException); |
|||
} |
|||
|
|||
/** |
|||
* A factory for creating the appropriate exception based on the response from Graph. |
|||
* |
|||
* @param FacebookResponse $response The response that threw the exception. |
|||
* |
|||
* @return FacebookResponseException |
|||
*/ |
|||
public static function create(FacebookResponse $response) |
|||
{ |
|||
$data = $response->getDecodedBody(); |
|||
|
|||
if (!isset($data['error']['code']) && isset($data['code'])) { |
|||
$data = ['error' => $data]; |
|||
} |
|||
|
|||
$code = isset($data['error']['code']) ? $data['error']['code'] : null; |
|||
$message = isset($data['error']['message']) ? $data['error']['message'] : 'Unknown error from Graph.'; |
|||
|
|||
$previousException = null; |
|||
|
|||
if (isset($data['error']['error_subcode'])) { |
|||
switch ($data['error']['error_subcode']) { |
|||
// Other authentication issues |
|||
case 458: |
|||
case 459: |
|||
case 460: |
|||
case 463: |
|||
case 464: |
|||
case 467: |
|||
return new static($response, new FacebookAuthenticationException($message, $code)); |
|||
} |
|||
} |
|||
|
|||
switch ($code) { |
|||
// Login status or token expired, revoked, or invalid |
|||
case 100: |
|||
case 102: |
|||
case 190: |
|||
return new static($response, new FacebookAuthenticationException($message, $code)); |
|||
|
|||
// Server issue, possible downtime |
|||
case 1: |
|||
case 2: |
|||
return new static($response, new FacebookServerException($message, $code)); |
|||
|
|||
// API Throttling |
|||
case 4: |
|||
case 17: |
|||
case 341: |
|||
return new static($response, new FacebookThrottleException($message, $code)); |
|||
|
|||
// Duplicate Post |
|||
case 506: |
|||
return new static($response, new FacebookClientException($message, $code)); |
|||
} |
|||
|
|||
// Missing Permissions |
|||
if ($code == 10 || ($code >= 200 && $code <= 299)) { |
|||
return new static($response, new FacebookAuthorizationException($message, $code)); |
|||
} |
|||
|
|||
// OAuth authentication error |
|||
if (isset($data['error']['type']) && $data['error']['type'] === 'OAuthException') { |
|||
return new static($response, new FacebookAuthenticationException($message, $code)); |
|||
} |
|||
|
|||
// All others |
|||
return new static($response, new FacebookOtherException($message, $code)); |
|||
} |
|||
|
|||
/** |
|||
* Checks isset and returns that or a default value. |
|||
* |
|||
* @param string $key |
|||
* @param mixed $default |
|||
* |
|||
* @return mixed |
|||
*/ |
|||
private function get($key, $default = null) |
|||
{ |
|||
if (isset($this->responseData['error'][$key])) { |
|||
return $this->responseData['error'][$key]; |
|||
} |
|||
|
|||
return $default; |
|||
} |
|||
|
|||
/** |
|||
* Returns the HTTP status code |
|||
* |
|||
* @return int |
|||
*/ |
|||
public function getHttpStatusCode() |
|||
{ |
|||
return $this->response->getHttpStatusCode(); |
|||
} |
|||
|
|||
/** |
|||
* Returns the sub-error code |
|||
* |
|||
* @return int |
|||
*/ |
|||
public function getSubErrorCode() |
|||
{ |
|||
return $this->get('error_subcode', -1); |
|||
} |
|||
|
|||
/** |
|||
* Returns the error type |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getErrorType() |
|||
{ |
|||
return $this->get('type', ''); |
|||
} |
|||
|
|||
/** |
|||
* Returns the raw response used to create the exception. |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getRawResponse() |
|||
{ |
|||
return $this->response->getBody(); |
|||
} |
|||
|
|||
/** |
|||
* Returns the decoded response used to create the exception. |
|||
* |
|||
* @return array |
|||
*/ |
|||
public function getResponseData() |
|||
{ |
|||
return $this->responseData; |
|||
} |
|||
|
|||
/** |
|||
* Returns the response entity used to create the exception. |
|||
* |
|||
* @return FacebookResponse |
|||
*/ |
|||
public function getResponse() |
|||
{ |
|||
return $this->response; |
|||
} |
|||
} |
@ -0,0 +1,33 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Exceptions; |
|||
|
|||
/** |
|||
* Class FacebookSDKException |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class FacebookSDKException extends \Exception |
|||
{ |
|||
} |
@ -0,0 +1,33 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Exceptions; |
|||
|
|||
/** |
|||
* Class FacebookServerException |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class FacebookServerException extends FacebookSDKException |
|||
{ |
|||
} |
@ -0,0 +1,33 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook\Exceptions; |
|||
|
|||
/** |
|||
* Class FacebookThrottleException |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class FacebookThrottleException extends FacebookSDKException |
|||
{ |
|||
} |
@ -0,0 +1,589 @@ |
|||
<?php |
|||
/** |
|||
* Copyright 2014 Facebook, Inc. |
|||
* |
|||
* You are hereby granted a non-exclusive, worldwide, royalty-free license to |
|||
* use, copy, modify, and distribute this software in source code or binary |
|||
* form for use in connection with the web services and APIs provided by |
|||
* Facebook. |
|||
* |
|||
* As with any software that integrates with the Facebook platform, your use |
|||
* of this software is subject to the Facebook Developer Principles and |
|||
* Policies [http://developers.facebook.com/policy/]. This copyright notice |
|||
* shall be included in all copies or substantial portions of the software. |
|||
* |
|||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
|||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
|||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
|||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
|||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
|||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
|||
* DEALINGS IN THE SOFTWARE. |
|||
* |
|||
*/ |
|||
namespace Facebook; |
|||
|
|||
use Facebook\Authentication\AccessToken; |
|||
use Facebook\Authentication\OAuth2Client; |
|||
use Facebook\FileUpload\FacebookFile; |
|||
use Facebook\FileUpload\FacebookVideo; |
|||
use Facebook\GraphNodes\GraphEdge; |
|||
use Facebook\Url\UrlDetectionInterface; |
|||
use Facebook\Url\FacebookUrlDetectionHandler; |
|||
use Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface; |
|||
use Facebook\PseudoRandomString\McryptPseudoRandomStringGenerator; |
|||
use Facebook\PseudoRandomString\OpenSslPseudoRandomStringGenerator; |
|||
use Facebook\PseudoRandomString\UrandomPseudoRandomStringGenerator; |
|||
use Facebook\HttpClients\FacebookHttpClientInterface; |
|||
use Facebook\HttpClients\FacebookCurlHttpClient; |
|||
use Facebook\HttpClients\FacebookStreamHttpClient; |
|||
use Facebook\HttpClients\FacebookGuzzleHttpClient; |
|||
use Facebook\PersistentData\PersistentDataInterface; |
|||
use Facebook\PersistentData\FacebookSessionPersistentDataHandler; |
|||
use Facebook\PersistentData\FacebookMemoryPersistentDataHandler; |
|||
use Facebook\Helpers\FacebookCanvasHelper; |
|||
use Facebook\Helpers\FacebookJavaScriptHelper; |
|||
use Facebook\Helpers\FacebookPageTabHelper; |
|||
use Facebook\Helpers\FacebookRedirectLoginHelper; |
|||
use Facebook\Exceptions\FacebookSDKException; |
|||
|
|||
/** |
|||
* Class Facebook |
|||
* |
|||
* @package Facebook |
|||
*/ |
|||
class Facebook |
|||
{ |
|||
/** |
|||
* @const string Version number of the Facebook PHP SDK. |
|||
*/ |
|||
const VERSION = '5.0.0'; |
|||
|
|||
/** |
|||
* @const string Default Graph API version for requests. |
|||
*/ |
|||
const DEFAULT_GRAPH_VERSION = 'v2.4'; |
|||
|
|||
/** |
|||
* @const string The name of the environment variable that contains the app ID. |
|||
*/ |
|||
const APP_ID_ENV_NAME = 'FACEBOOK_APP_ID'; |
|||
|
|||
/** |
|||
* @const string The name of the environment variable that contains the app secret. |
|||
*/ |
|||
const APP_SECRET_ENV_NAME = 'FACEBOOK_APP_SECRET'; |
|||
|
|||
/** |
|||
* @var FacebookApp The FacebookApp entity. |
|||
*/ |
|||
protected $app; |
|||
|
|||
/** |
|||
* @var FacebookClient The Facebook client service. |
|||
*/ |
|||
protected $client; |
|||
|
|||
/** |
|||
* @var OAuth2Client The OAuth 2.0 client service. |
|||
*/ |
|||
protected $oAuth2Client; |
|||
|
|||
/** |
|||
* @var UrlDetectionInterface|null The URL detection handler. |
|||
*/ |
|||
protected $urlDetectionHandler; |
|||
|
|||
/** |
|||
* @var PseudoRandomStringGeneratorInterface|null The cryptographically secure pseudo-random string generator. |
|||
*/ |
|||
protected $pseudoRandomStringGenerator; |
|||
|
|||
/** |
|||
* @var AccessToken|null The default access token to use with requests. |
|||
*/ |
|||
protected $defaultAccessToken; |
|||
|
|||
/** |
|||
* @var string|null The default Graph version we want to use. |
|||
*/ |
|||
protected $defaultGraphVersion; |
|||
|
|||
/** |
|||
* @var PersistentDataInterface|null The persistent data handler. |
|||
*/ |
|||
protected $persistentDataHandler; |
|||
|
|||
/** |
|||
* @var FacebookResponse|FacebookBatchResponse|null Stores the last request made to Graph. |
|||
*/ |
|||
protected $lastResponse; |
|||
|
|||
/** |
|||
* Instantiates a new Facebook super-class object. |
|||
* |
|||
* @param array $config |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function __construct(array $config = []) |
|||
{ |
|||
$appId = isset($config['app_id']) ? $config['app_id'] : getenv(static::APP_ID_ENV_NAME); |
|||
if (!$appId) { |
|||
throw new FacebookSDKException('Required "app_id" key not supplied in config and could not find fallback environment variable "' . static::APP_ID_ENV_NAME . '"'); |
|||
} |
|||
|
|||
$appSecret = isset($config['app_secret']) ? $config['app_secret'] : getenv(static::APP_SECRET_ENV_NAME); |
|||
if (!$appSecret) { |
|||
throw new FacebookSDKException('Required "app_secret" key not supplied in config and could not find fallback environment variable "' . static::APP_SECRET_ENV_NAME . '"'); |
|||
} |
|||
|
|||
$this->app = new FacebookApp($appId, $appSecret); |
|||
|
|||
$httpClientHandler = null; |
|||
if (isset($config['http_client_handler'])) { |
|||
if ($config['http_client_handler'] instanceof FacebookHttpClientInterface) { |
|||
$httpClientHandler = $config['http_client_handler']; |
|||
} elseif ($config['http_client_handler'] === 'curl') { |
|||
$httpClientHandler = new FacebookCurlHttpClient(); |
|||
} elseif ($config['http_client_handler'] === 'stream') { |
|||
$httpClientHandler = new FacebookStreamHttpClient(); |
|||
} elseif ($config['http_client_handler'] === 'guzzle') { |
|||
$httpClientHandler = new FacebookGuzzleHttpClient(); |
|||
} else { |
|||
throw new \InvalidArgumentException('The http_client_handler must be set to "curl", "stream", "guzzle", or be an instance of Facebook\HttpClients\FacebookHttpClientInterface'); |
|||
} |
|||
} |
|||
|
|||
$enableBeta = isset($config['enable_beta_mode']) && $config['enable_beta_mode'] === true; |
|||
$this->client = new FacebookClient($httpClientHandler, $enableBeta); |
|||
|
|||
if (isset($config['url_detection_handler'])) { |
|||
if ($config['url_detection_handler'] instanceof UrlDetectionInterface) { |
|||
$this->urlDetectionHandler = $config['url_detection_handler']; |
|||
} else { |
|||
throw new \InvalidArgumentException('The url_detection_handler must be an instance of Facebook\Url\UrlDetectionInterface'); |
|||
} |
|||
} |
|||
|
|||
if (isset($config['pseudo_random_string_generator'])) { |
|||
if ($config['pseudo_random_string_generator'] instanceof PseudoRandomStringGeneratorInterface) { |
|||
$this->pseudoRandomStringGenerator = $config['pseudo_random_string_generator']; |
|||
} elseif ($config['pseudo_random_string_generator'] === 'mcrypt') { |
|||
$this->pseudoRandomStringGenerator = new McryptPseudoRandomStringGenerator(); |
|||
} elseif ($config['pseudo_random_string_generator'] === 'openssl') { |
|||
$this->pseudoRandomStringGenerator = new OpenSslPseudoRandomStringGenerator(); |
|||
} elseif ($config['pseudo_random_string_generator'] === 'urandom') { |
|||
$this->pseudoRandomStringGenerator = new UrandomPseudoRandomStringGenerator(); |
|||
} else { |
|||
throw new \InvalidArgumentException('The pseudo_random_string_generator must be set to "mcrypt", "openssl", or "urandom", or be an instance of Facebook\PseudoRandomString\PseudoRandomStringGeneratorInterface'); |
|||
} |
|||
} |
|||
|
|||
if (isset($config['persistent_data_handler'])) { |
|||
if ($config['persistent_data_handler'] instanceof PersistentDataInterface) { |
|||
$this->persistentDataHandler = $config['persistent_data_handler']; |
|||
} elseif ($config['persistent_data_handler'] === 'session') { |
|||
$this->persistentDataHandler = new FacebookSessionPersistentDataHandler(); |
|||
} elseif ($config['persistent_data_handler'] === 'memory') { |
|||
$this->persistentDataHandler = new FacebookMemoryPersistentDataHandler(); |
|||
} else { |
|||
throw new \InvalidArgumentException('The persistent_data_handler must be set to "session", "memory", or be an instance of Facebook\PersistentData\PersistentDataInterface'); |
|||
} |
|||
} |
|||
|
|||
if (isset($config['default_access_token'])) { |
|||
$this->setDefaultAccessToken($config['default_access_token']); |
|||
} |
|||
|
|||
if (isset($config['default_graph_version'])) { |
|||
$this->defaultGraphVersion = $config['default_graph_version']; |
|||
} else { |
|||
// @todo v6: Throw an InvalidArgumentException if "default_graph_version" is not set |
|||
$this->defaultGraphVersion = static::DEFAULT_GRAPH_VERSION; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* Returns the FacebookApp entity. |
|||
* |
|||
* @return FacebookApp |
|||
*/ |
|||
public function getApp() |
|||
{ |
|||
return $this->app; |
|||
} |
|||
|
|||
/** |
|||
* Returns the FacebookClient service. |
|||
* |
|||
* @return FacebookClient |
|||
*/ |
|||
public function getClient() |
|||
{ |
|||
return $this->client; |
|||
} |
|||
|
|||
/** |
|||
* Returns the OAuth 2.0 client service. |
|||
* |
|||
* @return OAuth2Client |
|||
*/ |
|||
public function getOAuth2Client() |
|||
{ |
|||
if (!$this->oAuth2Client instanceof OAuth2Client) { |
|||
$app = $this->getApp(); |
|||
$client = $this->getClient(); |
|||
$this->oAuth2Client = new OAuth2Client($app, $client, $this->defaultGraphVersion); |
|||
} |
|||
|
|||
return $this->oAuth2Client; |
|||
} |
|||
|
|||
/** |
|||
* Returns the last response returned from Graph. |
|||
* |
|||
* @return FacebookResponse|FacebookBatchResponse|null |
|||
*/ |
|||
public function getLastResponse() |
|||
{ |
|||
return $this->lastResponse; |
|||
} |
|||
|
|||
/** |
|||
* Returns the URL detection handler. |
|||
* |
|||
* @return UrlDetectionInterface |
|||
*/ |
|||
public function getUrlDetectionHandler() |
|||
{ |
|||
if (!$this->urlDetectionHandler instanceof UrlDetectionInterface) { |
|||
$this->urlDetectionHandler = new FacebookUrlDetectionHandler(); |
|||
} |
|||
|
|||
return $this->urlDetectionHandler; |
|||
} |
|||
|
|||
/** |
|||
* Returns the default AccessToken entity. |
|||
* |
|||
* @return AccessToken|null |
|||
*/ |
|||
public function getDefaultAccessToken() |
|||
{ |
|||
return $this->defaultAccessToken; |
|||
} |
|||
|
|||
/** |
|||
* Sets the default access token to use with requests. |
|||
* |
|||
* @param AccessToken|string $accessToken The access token to save. |
|||
* |
|||
* @throws \InvalidArgumentException |
|||
*/ |
|||
public function setDefaultAccessToken($accessToken) |
|||
{ |
|||
if (is_string($accessToken)) { |
|||
$this->defaultAccessToken = new AccessToken($accessToken); |
|||
|
|||
return; |
|||
} |
|||
|
|||
if ($accessToken instanceof AccessToken) { |
|||
$this->defaultAccessToken = $accessToken; |
|||
|
|||
return; |
|||
} |
|||
|
|||
throw new \InvalidArgumentException('The default access token must be of type "string" or Facebook\AccessToken'); |
|||
} |
|||
|
|||
/** |
|||
* Returns the default Graph version. |
|||
* |
|||
* @return string |
|||
*/ |
|||
public function getDefaultGraphVersion() |
|||
{ |
|||
return $this->defaultGraphVersion; |
|||
} |
|||
|
|||
/** |
|||
* Returns the redirect login helper. |
|||
* |
|||
* @return FacebookRedirectLoginHelper |
|||
*/ |
|||
public function getRedirectLoginHelper() |
|||
{ |
|||
return new FacebookRedirectLoginHelper( |
|||
$this->getOAuth2Client(), |
|||
$this->persistentDataHandler, |
|||
$this->urlDetectionHandler, |
|||
$this->pseudoRandomStringGenerator |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* Returns the JavaScript helper. |
|||
* |
|||
* @return FacebookJavaScriptHelper |
|||
*/ |
|||
public function getJavaScriptHelper() |
|||
{ |
|||
return new FacebookJavaScriptHelper($this->app, $this->client, $this->defaultGraphVersion); |
|||
} |
|||
|
|||
/** |
|||
* Returns the canvas helper. |
|||
* |
|||
* @return FacebookCanvasHelper |
|||
*/ |
|||
public function getCanvasHelper() |
|||
{ |
|||
return new FacebookCanvasHelper($this->app, $this->client, $this->defaultGraphVersion); |
|||
} |
|||
|
|||
/** |
|||
* Returns the page tab helper. |
|||
* |
|||
* @return FacebookPageTabHelper |
|||
*/ |
|||
public function getPageTabHelper() |
|||
{ |
|||
return new FacebookPageTabHelper($this->app, $this->client, $this->defaultGraphVersion); |
|||
} |
|||
|
|||
/** |
|||
* Sends a GET request to Graph and returns the result. |
|||
* |
|||
* @param string $endpoint |
|||
* @param AccessToken|string|null $accessToken |
|||
* @param string|null $eTag |
|||
* @param string|null $graphVersion |
|||
* |
|||
* @return FacebookResponse |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function get($endpoint, $accessToken = null, $eTag = null, $graphVersion = null) |
|||
{ |
|||
return $this->sendRequest( |
|||
'GET', |
|||
$endpoint, |
|||
$params = [], |
|||
$accessToken, |
|||
$eTag, |
|||
$graphVersion |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* Sends a POST request to Graph and returns the result. |
|||
* |
|||
* @param string $endpoint |
|||
* @param array $params |
|||
* @param AccessToken|string|null $accessToken |
|||
* @param string|null $eTag |
|||
* @param string|null $graphVersion |
|||
* |
|||
* @return FacebookResponse |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function post($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) |
|||
{ |
|||
return $this->sendRequest( |
|||
'POST', |
|||
$endpoint, |
|||
$params, |
|||
$accessToken, |
|||
$eTag, |
|||
$graphVersion |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* Sends a DELETE request to Graph and returns the result. |
|||
* |
|||
* @param string $endpoint |
|||
* @param array $params |
|||
* @param AccessToken|string|null $accessToken |
|||
* @param string|null $eTag |
|||
* @param string|null $graphVersion |
|||
* |
|||
* @return FacebookResponse |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function delete($endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) |
|||
{ |
|||
return $this->sendRequest( |
|||
'DELETE', |
|||
$endpoint, |
|||
$params, |
|||
$accessToken, |
|||
$eTag, |
|||
$graphVersion |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* Sends a request to Graph for the next page of results. |
|||
* |
|||
* @param GraphEdge $graphEdge The GraphEdge to paginate over. |
|||
* |
|||
* @return GraphEdge|null |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function next(GraphEdge $graphEdge) |
|||
{ |
|||
return $this->getPaginationResults($graphEdge, 'next'); |
|||
} |
|||
|
|||
/** |
|||
* Sends a request to Graph for the previous page of results. |
|||
* |
|||
* @param GraphEdge $graphEdge The GraphEdge to paginate over. |
|||
* |
|||
* @return GraphEdge|null |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function previous(GraphEdge $graphEdge) |
|||
{ |
|||
return $this->getPaginationResults($graphEdge, 'previous'); |
|||
} |
|||
|
|||
/** |
|||
* Sends a request to Graph for the next page of results. |
|||
* |
|||
* @param GraphEdge $graphEdge The GraphEdge to paginate over. |
|||
* @param string $direction The direction of the pagination: next|previous. |
|||
* |
|||
* @return GraphEdge|null |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function getPaginationResults(GraphEdge $graphEdge, $direction) |
|||
{ |
|||
$paginationRequest = $graphEdge->getPaginationRequest($direction); |
|||
if (!$paginationRequest) { |
|||
return null; |
|||
} |
|||
|
|||
$this->lastResponse = $this->client->sendRequest($paginationRequest); |
|||
|
|||
// Keep the same GraphNode subclass |
|||
$subClassName = $graphEdge->getSubClassName(); |
|||
$graphEdge = $this->lastResponse->getGraphEdge($subClassName, false); |
|||
|
|||
return count($graphEdge) > 0 ? $graphEdge : null; |
|||
} |
|||
|
|||
/** |
|||
* Sends a request to Graph and returns the result. |
|||
* |
|||
* @param string $method |
|||
* @param string $endpoint |
|||
* @param array $params |
|||
* @param AccessToken|string|null $accessToken |
|||
* @param string|null $eTag |
|||
* @param string|null $graphVersion |
|||
* |
|||
* @return FacebookResponse |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function sendRequest($method, $endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) |
|||
{ |
|||
$accessToken = $accessToken ?: $this->defaultAccessToken; |
|||
$graphVersion = $graphVersion ?: $this->defaultGraphVersion; |
|||
$request = $this->request($method, $endpoint, $params, $accessToken, $eTag, $graphVersion); |
|||
|
|||
return $this->lastResponse = $this->client->sendRequest($request); |
|||
} |
|||
|
|||
/** |
|||
* Sends a batched request to Graph and returns the result. |
|||
* |
|||
* @param array $requests |
|||
* @param AccessToken|string|null $accessToken |
|||
* @param string|null $graphVersion |
|||
* |
|||
* @return FacebookBatchResponse |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function sendBatchRequest(array $requests, $accessToken = null, $graphVersion = null) |
|||
{ |
|||
$accessToken = $accessToken ?: $this->defaultAccessToken; |
|||
$graphVersion = $graphVersion ?: $this->defaultGraphVersion; |
|||
$batchRequest = new FacebookBatchRequest( |
|||
$this->app, |
|||
$requests, |
|||
$accessToken, |
|||
$graphVersion |
|||
); |
|||
|
|||
return $this->lastResponse = $this->client->sendBatchRequest($batchRequest); |
|||
} |
|||
|
|||
/** |
|||
* Instantiates a new FacebookRequest entity. |
|||
* |
|||
* @param string $method |
|||
* @param string $endpoint |
|||
* @param array $params |
|||
* @param AccessToken|string|null $accessToken |
|||
* @param string|null $eTag |
|||
* @param string|null $graphVersion |
|||
* |
|||
* @return FacebookRequest |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function request($method, $endpoint, array $params = [], $accessToken = null, $eTag = null, $graphVersion = null) |
|||
{ |
|||
$accessToken = $accessToken ?: $this->defaultAccessToken; |
|||
$graphVersion = $graphVersion ?: $this->defaultGraphVersion; |
|||
|
|||
return new FacebookRequest( |
|||
$this->app, |
|||
$accessToken, |
|||
$method, |
|||
$endpoint, |
|||
$params, |
|||
$eTag, |
|||
$graphVersion |
|||
); |
|||
} |
|||
|
|||
/** |
|||
* Factory to create FacebookFile's. |
|||
* |
|||
* @param string $pathToFile |
|||
* |
|||
* @return FacebookFile |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function fileToUpload($pathToFile) |
|||
{ |
|||
return new FacebookFile($pathToFile); |
|||
} |
|||
|
|||
/** |
|||
* Factory to create FacebookVideo's. |
|||
* |
|||
* @param string $pathToFile |
|||
* |
|||
* @return FacebookVideo |
|||
* |
|||
* @throws FacebookSDKException |
|||
*/ |
|||
public function videoToUpload($pathToFile) |
|||
{ |
|||