parent
6431b0001d
commit
bc19d977eb
@ -0,0 +1,70 @@ |
||||
<?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. |
||||
* |
||||
*/ |
||||
|
||||
/** |
||||
* You only need this file if you are not using composer. |
||||
* Why are you not using composer? |
||||
* https://getcomposer.org/ |
||||
*/ |
||||
|
||||
if (version_compare(PHP_VERSION, '5.4.0', '<')) { |
||||
throw new Exception('The Facebook SDK v4 requires PHP version 5.4 or higher.'); |
||||
} |
||||
|
||||
/** |
||||
* Register the autoloader for the Facebook SDK classes. |
||||
* Based off the official PSR-4 autoloader example found here: |
||||
* https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader-examples.md |
||||
* |
||||
* @param string $class The fully-qualified class name. |
||||
* @return void |
||||
*/ |
||||
spl_autoload_register(function ($class) |
||||
{ |
||||
// project-specific namespace prefix |
||||
$prefix = 'Facebook\\'; |
||||
|
||||
// base directory for the namespace prefix |
||||
$base_dir = defined('FACEBOOK_SDK_V4_SRC_DIR') ? FACEBOOK_SDK_V4_SRC_DIR : __DIR__ . '/src/Facebook/'; |
||||
|
||||
// does the class use the namespace prefix? |
||||
$len = strlen($prefix); |
||||
if (strncmp($prefix, $class, $len) !== 0) { |
||||
// no, move to the next registered autoloader |
||||
return; |
||||
} |
||||
|
||||
// get the relative class name |
||||
$relative_class = substr($class, $len); |
||||
|
||||
// replace the namespace prefix with the base directory, replace namespace |
||||
// separators with directory separators in the relative class name, append |
||||
// with .php |
||||
$file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; |
||||
|
||||
// if the file exists, require it |
||||
if (file_exists($file)) { |
||||
require $file; |
||||
} |
||||
}); |
@ -0,0 +1,380 @@ |
||||
<?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\Entities; |
||||
|
||||
use Facebook\FacebookRequest; |
||||
use Facebook\FacebookRequestException; |
||||
use Facebook\FacebookSession; |
||||
use Facebook\GraphSessionInfo; |
||||
|
||||
/** |
||||
* Class AccessToken |
||||
* @package Facebook |
||||
*/ |
||||
class AccessToken |
||||
{ |
||||
|
||||
/** |
||||
* The access token. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $accessToken; |
||||
|
||||
/** |
||||
* A unique ID to identify a client. |
||||
* |
||||
* @var string |
||||
*/ |
||||
protected $machineId; |
||||
|
||||
/** |
||||
* Date when token expires. |
||||
* |
||||
* @var \DateTime|null |
||||
*/ |
||||
protected $expiresAt; |
||||
|
||||
/** |
||||
* Create a new access token entity. |
||||
* |
||||
* @param string $accessToken |
||||
* @param int $expiresAt |
||||
* @param string|null machineId |
||||
*/ |
||||
public function __construct($accessToken, $expiresAt = 0, $machineId = null) |
||||
{ |
||||
$this->accessToken = $accessToken; |
||||
if ($expiresAt) { |
||||
$this->setExpiresAtFromTimeStamp($expiresAt); |
||||
} |
||||
$this->machineId = $machineId; |
||||
} |
||||
|
||||
/** |
||||
* Setter for expires_at. |
||||
* |
||||
* @param int $timeStamp |
||||
*/ |
||||
protected function setExpiresAtFromTimeStamp($timeStamp) |
||||
{ |
||||
$dt = new \DateTime(); |
||||
$dt->setTimestamp($timeStamp); |
||||
$this->expiresAt = $dt; |
||||
} |
||||
|
||||
/** |
||||
* Getter for expiresAt. |
||||
* |
||||
* @return \DateTime|null |
||||
*/ |
||||
public function getExpiresAt() |
||||
{ |
||||
return $this->expiresAt; |
||||
} |
||||
|
||||
/** |
||||
* Getter for machineId. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getMachineId() |
||||
{ |
||||
return $this->machineId; |
||||
} |
||||
|
||||
/** |
||||
* 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); |
||||
} |
||||
return false; |
||||
} |
||||
|
||||
/** |
||||
* Checks the validity of the access token. |
||||
* |
||||
* @param string|null $appId Application ID to use |
||||
* @param string|null $appSecret App secret value to use |
||||
* @param string|null $machineId |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function isValid($appId = null, $appSecret = null, $machineId = null) |
||||
{ |
||||
$accessTokenInfo = $this->getInfo($appId, $appSecret); |
||||
$machineId = $machineId ?: $this->machineId; |
||||
return static::validateAccessToken($accessTokenInfo, $appId, $machineId); |
||||
} |
||||
|
||||
/** |
||||
* Ensures the provided GraphSessionInfo object is valid, |
||||
* throwing an exception if not. Ensures the appId matches, |
||||
* that the machineId matches if it's being used, |
||||
* that the token is valid and has not expired. |
||||
* |
||||
* @param GraphSessionInfo $tokenInfo |
||||
* @param string|null $appId Application ID to use |
||||
* @param string|null $machineId |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public static function validateAccessToken(GraphSessionInfo $tokenInfo, |
||||
$appId = null, $machineId = null) |
||||
{ |
||||
$targetAppId = FacebookSession::_getTargetAppId($appId); |
||||
|
||||
$appIdIsValid = $tokenInfo->getAppId() == $targetAppId; |
||||
$machineIdIsValid = $tokenInfo->getProperty('machine_id') == $machineId; |
||||
$accessTokenIsValid = $tokenInfo->isValid(); |
||||
|
||||
// Not all access tokens return an expiration. E.g. an app access token. |
||||
if ($tokenInfo->getExpiresAt() instanceof \DateTime) { |
||||
$accessTokenIsStillAlive = $tokenInfo->getExpiresAt()->getTimestamp() >= time(); |
||||
} else { |
||||
$accessTokenIsStillAlive = true; |
||||
} |
||||
|
||||
return $appIdIsValid && $machineIdIsValid && $accessTokenIsValid && $accessTokenIsStillAlive; |
||||
} |
||||
|
||||
/** |
||||
* Get a valid access token from a code. |
||||
* |
||||
* @param string $code |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
* @param string|null $machineId |
||||
* |
||||
* @return AccessToken |
||||
*/ |
||||
public static function getAccessTokenFromCode($code, $appId = null, $appSecret = null, $machineId = null) |
||||
{ |
||||
$params = array( |
||||
'code' => $code, |
||||
'redirect_uri' => '', |
||||
); |
||||
|
||||
if ($machineId) { |
||||
$params['machine_id'] = $machineId; |
||||
} |
||||
|
||||
return static::requestAccessToken($params, $appId, $appSecret); |
||||
} |
||||
|
||||
/** |
||||
* Get a valid code from an access token. |
||||
* |
||||
* @param AccessToken|string $accessToken |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return AccessToken |
||||
*/ |
||||
public static function getCodeFromAccessToken($accessToken, $appId = null, $appSecret = null) |
||||
{ |
||||
$accessToken = (string) $accessToken; |
||||
|
||||
$params = array( |
||||
'access_token' => $accessToken, |
||||
'redirect_uri' => '', |
||||
); |
||||
|
||||
return static::requestCode($params, $appId, $appSecret); |
||||
} |
||||
|
||||
/** |
||||
* Exchanges a short lived access token with a long lived access token. |
||||
* |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return AccessToken |
||||
*/ |
||||
public function extend($appId = null, $appSecret = null) |
||||
{ |
||||
$params = array( |
||||
'grant_type' => 'fb_exchange_token', |
||||
'fb_exchange_token' => $this->accessToken, |
||||
); |
||||
|
||||
return static::requestAccessToken($params, $appId, $appSecret); |
||||
} |
||||
|
||||
/** |
||||
* Request an access token based on a set of params. |
||||
* |
||||
* @param array $params |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return AccessToken |
||||
* |
||||
* @throws FacebookRequestException |
||||
*/ |
||||
public static function requestAccessToken(array $params, $appId = null, $appSecret = null) |
||||
{ |
||||
$response = static::request('/oauth/access_token', $params, $appId, $appSecret); |
||||
$data = $response->getResponse(); |
||||
|
||||
/** |
||||
* @TODO fix this malarkey - getResponse() should always return an object |
||||
* @see https://github.com/facebook/facebook-php-sdk-v4/issues/36 |
||||
*/ |
||||
if (is_array($data)) { |
||||
if (isset($data['access_token'])) { |
||||
$expiresAt = isset($data['expires']) ? time() + $data['expires'] : 0; |
||||
return new static($data['access_token'], $expiresAt); |
||||
} |
||||
} elseif($data instanceof \stdClass) { |
||||
if (isset($data->access_token)) { |
||||
$expiresAt = isset($data->expires_in) ? time() + $data->expires_in : 0; |
||||
$machineId = isset($data->machine_id) ? (string) $data->machine_id : null; |
||||
return new static((string) $data->access_token, $expiresAt, $machineId); |
||||
} |
||||
} |
||||
|
||||
throw FacebookRequestException::create( |
||||
$response->getRawResponse(), |
||||
$data, |
||||
401 |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Request a code from a long lived access token. |
||||
* |
||||
* @param array $params |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return string |
||||
* |
||||
* @throws FacebookRequestException |
||||
*/ |
||||
public static function requestCode(array $params, $appId = null, $appSecret = null) |
||||
{ |
||||
$response = static::request('/oauth/client_code', $params, $appId, $appSecret); |
||||
$data = $response->getResponse(); |
||||
|
||||
if (isset($data->code)) { |
||||
return (string) $data->code; |
||||
} |
||||
|
||||
throw FacebookRequestException::create( |
||||
$response->getRawResponse(), |
||||
$data, |
||||
401 |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Send a request to Graph with an app access token. |
||||
* |
||||
* @param string $endpoint |
||||
* @param array $params |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return \Facebook\FacebookResponse |
||||
* |
||||
* @throws FacebookRequestException |
||||
*/ |
||||
protected static function request($endpoint, array $params, $appId = null, $appSecret = null) |
||||
{ |
||||
$targetAppId = FacebookSession::_getTargetAppId($appId); |
||||
$targetAppSecret = FacebookSession::_getTargetAppSecret($appSecret); |
||||
|
||||
if (!isset($params['client_id'])) { |
||||
$params['client_id'] = $targetAppId; |
||||
} |
||||
if (!isset($params['client_secret'])) { |
||||
$params['client_secret'] = $targetAppSecret; |
||||
} |
||||
|
||||
// The response for this endpoint is not JSON, so it must be handled |
||||
// differently, not as a GraphObject. |
||||
$request = new FacebookRequest( |
||||
FacebookSession::newAppSession($targetAppId, $targetAppSecret), |
||||
'GET', |
||||
$endpoint, |
||||
$params |
||||
); |
||||
return $request->execute(); |
||||
} |
||||
|
||||
/** |
||||
* Get more info about an access token. |
||||
* |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return GraphSessionInfo |
||||
*/ |
||||
public function getInfo($appId = null, $appSecret = null) |
||||
{ |
||||
$params = array('input_token' => $this->accessToken); |
||||
|
||||
$request = new FacebookRequest( |
||||
FacebookSession::newAppSession($appId, $appSecret), |
||||
'GET', |
||||
'/debug_token', |
||||
$params |
||||
); |
||||
$response = $request->execute()->getGraphObject(GraphSessionInfo::className()); |
||||
|
||||
// Update the data on this token |
||||
if ($response->getExpiresAt()) { |
||||
$this->expiresAt = $response->getExpiresAt(); |
||||
} |
||||
|
||||
return $response; |
||||
} |
||||
|
||||
/** |
||||
* Returns the access token as a string. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function __toString() |
||||
{ |
||||
return $this->accessToken; |
||||
} |
||||
|
||||
/** |
||||
* Returns true if the access token is an app session token. |
||||
* |
||||
* @return bool |
||||
*/ |
||||
public function isAppSession() |
||||
{ |
||||
return strpos($this->accessToken, "|") !== false; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,386 @@ |
||||
<?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\Entities; |
||||
|
||||
use Facebook\FacebookSDKException; |
||||
use Facebook\FacebookSession; |
||||
|
||||
/** |
||||
* Class SignedRequest |
||||
* @package Facebook |
||||
*/ |
||||
class SignedRequest |
||||
{ |
||||
|
||||
/** |
||||
* @var string |
||||
*/ |
||||
public $rawSignedRequest; |
||||
|
||||
/** |
||||
* @var array |
||||
*/ |
||||
public $payload; |
||||
|
||||
/** |
||||
* Instantiate a new SignedRequest entity. |
||||
* |
||||
* @param string|null $rawSignedRequest The raw signed request. |
||||
* @param string|null $state random string to prevent CSRF. |
||||
* @param string|null $appSecret |
||||
*/ |
||||
public function __construct($rawSignedRequest = null, $state = null, $appSecret = null) |
||||
{ |
||||
if (!$rawSignedRequest) { |
||||
return; |
||||
} |
||||
|
||||
$this->rawSignedRequest = $rawSignedRequest; |
||||
$this->payload = static::parse($rawSignedRequest, $state, $appSecret); |
||||
} |
||||
|
||||
/** |
||||
* Returns the raw signed request data. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getRawSignedRequest() |
||||
{ |
||||
return $this->rawSignedRequest; |
||||
} |
||||
|
||||
/** |
||||
* Returns the parsed signed request data. |
||||
* |
||||
* @return array|null |
||||
*/ |
||||
public function getPayload() |
||||
{ |
||||
return $this->payload; |
||||
} |
||||
|
||||
/** |
||||
* Returns a property from the signed request data if available. |
||||
* |
||||
* @param string $key |
||||
* @param mixed|null $default |
||||
* |
||||
* @return mixed|null |
||||
*/ |
||||
public function get($key, $default = null) |
||||
{ |
||||
if (isset($this->payload[$key])) { |
||||
return $this->payload[$key]; |
||||
} |
||||
return $default; |
||||
} |
||||
|
||||
/** |
||||
* Returns user_id from signed request data if available. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getUserId() |
||||
{ |
||||
return $this->get('user_id'); |
||||
} |
||||
|
||||
/** |
||||
* Checks for OAuth data in the payload. |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function hasOAuthData() |
||||
{ |
||||
return isset($this->payload['oauth_token']) || isset($this->payload['code']); |
||||
} |
||||
|
||||
/** |
||||
* Creates a signed request from an array of data. |
||||
* |
||||
* @param array $payload |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return string |
||||
*/ |
||||
public static function make(array $payload, $appSecret = null) |
||||
{ |
||||
$payload['algorithm'] = 'HMAC-SHA256'; |
||||
$payload['issued_at'] = time(); |
||||
$encodedPayload = static::base64UrlEncode(json_encode($payload)); |
||||
|
||||
$hashedSig = static::hashSignature($encodedPayload, $appSecret); |
||||
$encodedSig = static::base64UrlEncode($hashedSig); |
||||
|
||||
return $encodedSig.'.'.$encodedPayload; |
||||
} |
||||
|
||||
/** |
||||
* Validates and decodes a signed request and returns |
||||
* the payload as an array. |
||||
* |
||||
* @param string $signedRequest |
||||
* @param string|null $state |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return array |
||||
*/ |
||||
public static function parse($signedRequest, $state = null, $appSecret = null) |
||||
{ |
||||
list($encodedSig, $encodedPayload) = static::split($signedRequest); |
||||
|
||||
// Signature validation |
||||
$sig = static::decodeSignature($encodedSig); |
||||
$hashedSig = static::hashSignature($encodedPayload, $appSecret); |
||||
static::validateSignature($hashedSig, $sig); |
||||
|
||||
// Payload validation |
||||
$data = static::decodePayload($encodedPayload); |
||||
static::validateAlgorithm($data); |
||||
if ($state) { |
||||
static::validateCsrf($data, $state); |
||||
} |
||||
|
||||
return $data; |
||||
} |
||||
|
||||
/** |
||||
* Validates the format of a signed request. |
||||
* |
||||
* @param string $signedRequest |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function validateFormat($signedRequest) |
||||
{ |
||||
if (strpos($signedRequest, '.') !== false) { |
||||
return; |
||||
} |
||||
|
||||
throw new FacebookSDKException( |
||||
'Malformed signed request.', 606 |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Decodes a raw valid signed request. |
||||
* |
||||
* @param string $signedRequest |
||||
* |
||||
* @returns array |
||||
*/ |
||||
public static function split($signedRequest) |
||||
{ |
||||
static::validateFormat($signedRequest); |
||||
|
||||
return explode('.', $signedRequest, 2); |
||||
} |
||||
|
||||
/** |
||||
* Decodes the raw signature from a signed request. |
||||
* |
||||
* @param string $encodedSig |
||||
* |
||||
* @returns string |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function decodeSignature($encodedSig) |
||||
{ |
||||
$sig = static::base64UrlDecode($encodedSig); |
||||
|
||||
if ($sig) { |
||||
return $sig; |
||||
} |
||||
|
||||
throw new FacebookSDKException( |
||||
'Signed request has malformed encoded signature data.', 607 |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Decodes the raw payload from a signed request. |
||||
* |
||||
* @param string $encodedPayload |
||||
* |
||||
* @returns array |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function decodePayload($encodedPayload) |
||||
{ |
||||
$payload = static::base64UrlDecode($encodedPayload); |
||||
|
||||
if ($payload) { |
||||
$payload = json_decode($payload, true); |
||||
} |
||||
|
||||
if (is_array($payload)) { |
||||
return $payload; |
||||
} |
||||
|
||||
throw new FacebookSDKException( |
||||
'Signed request has malformed encoded payload data.', 607 |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Validates the algorithm used in a signed request. |
||||
* |
||||
* @param array $data |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function validateAlgorithm(array $data) |
||||
{ |
||||
if (isset($data['algorithm']) && $data['algorithm'] === 'HMAC-SHA256') { |
||||
return; |
||||
} |
||||
|
||||
throw new FacebookSDKException( |
||||
'Signed request is using the wrong algorithm.', 605 |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Hashes the signature used in a signed request. |
||||
* |
||||
* @param string $encodedData |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return string |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function hashSignature($encodedData, $appSecret = null) |
||||
{ |
||||
$hashedSig = hash_hmac( |
||||
'sha256', $encodedData, FacebookSession::_getTargetAppSecret($appSecret), $raw_output = true |
||||
); |
||||
|
||||
if ($hashedSig) { |
||||
return $hashedSig; |
||||
} |
||||
|
||||
throw new FacebookSDKException( |
||||
'Unable to hash signature from encoded payload data.', 602 |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Validates the signature used in a signed request. |
||||
* |
||||
* @param string $hashedSig |
||||
* @param string $sig |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function validateSignature($hashedSig, $sig) |
||||
{ |
||||
if (mb_strlen($hashedSig) === mb_strlen($sig)) { |
||||
$validate = 0; |
||||
for ($i = 0; $i < mb_strlen($sig); $i++) { |
||||
$validate |= ord($hashedSig[$i]) ^ ord($sig[$i]); |
||||
} |
||||
if ($validate === 0) { |
||||
return; |
||||
} |
||||
} |
||||
|
||||
throw new FacebookSDKException( |
||||
'Signed request has an invalid signature.', 602 |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Validates a signed request against CSRF. |
||||
* |
||||
* @param array $data |
||||
* @param string $state |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function validateCsrf(array $data, $state) |
||||
{ |
||||
if (isset($data['state']) && $data['state'] === $state) { |
||||
return; |
||||
} |
||||
|
||||
throw new FacebookSDKException( |
||||
'Signed request did not pass CSRF validation.', 604 |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Base64 decoding which replaces characters: |
||||
* + instead of - |
||||
* / instead of _ |
||||
* @link http://en.wikipedia.org/wiki/Base64#URL_applications |
||||
* |
||||
* @param string $input base64 url encoded input |
||||
* |
||||
* @return string decoded string |
||||
*/ |
||||
public static function base64UrlDecode($input) |
||||
{ |
||||
$urlDecodedBase64 = strtr($input, '-_', '+/'); |
||||
static::validateBase64($urlDecodedBase64); |
||||
return base64_decode($urlDecodedBase64); |
||||
} |
||||
|
||||
/** |
||||
* Base64 encoding which replaces characters: |
||||
* + instead of - |
||||
* / instead of _ |
||||
* @link http://en.wikipedia.org/wiki/Base64#URL_applications |
||||
* |
||||
* @param string $input string to encode |
||||
* |
||||
* @return string base64 url encoded input |
||||
*/ |
||||
public static function base64UrlEncode($input) |
||||
{ |
||||
return strtr(base64_encode($input), '+/', '-_'); |
||||
} |
||||
|
||||
/** |
||||
* Validates a base64 string. |
||||
* |
||||
* @param string $input base64 value to validate |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function validateBase64($input) |
||||
{ |
||||
$pattern = '/^[a-zA-Z0-9\/\r\n+]*={0,2}$/'; |
||||
if (preg_match($pattern, $input)) { |
||||
return; |
||||
} |
||||
|
||||
throw new FacebookSDKException( |
||||
'Signed request contains malformed base64 encoding.', 608 |
||||
); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
|
||||
/** |
||||
* Class FacebookAuthorizationException |
||||
* @package Facebook |
||||
*/ |
||||
class FacebookAuthorizationException extends FacebookRequestException |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,60 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class FacebookCanvasLoginHelper |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class FacebookCanvasLoginHelper extends FacebookSignedRequestFromInputHelper |
||||
{ |
||||
|
||||
/** |
||||
* Returns the app data value. |
||||
* |
||||
* @return mixed|null |
||||
*/ |
||||
public function getAppData() |
||||
{ |
||||
return $this->signedRequest ? $this->signedRequest->get('app_data') : null; |
||||
} |
||||
|
||||
/** |
||||
* Get raw signed request from POST. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getRawSignedRequest() |
||||
{ |
||||
$rawSignedRequest = $this->getRawSignedRequestFromPost(); |
||||
if ($rawSignedRequest) { |
||||
return $rawSignedRequest; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
|
||||
/** |
||||
* Class FacebookClientException |
||||
* @package Facebook |
||||
*/ |
||||
class FacebookClientException extends FacebookRequestException |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,45 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class FacebookJavaScriptLoginHelper |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class FacebookJavaScriptLoginHelper extends FacebookSignedRequestFromInputHelper |
||||
{ |
||||
|
||||
/** |
||||
* Get raw signed request from the cookie. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getRawSignedRequest() |
||||
{ |
||||
return $this->getRawSignedRequestFromCookie(); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
|
||||
/** |
||||
* Class FacebookOtherException |
||||
* @package Facebook |
||||
*/ |
||||
class FacebookOtherException extends FacebookRequestException |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,102 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class FacebookPageTabHelper |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
*/ |
||||
class FacebookPageTabHelper extends FacebookCanvasLoginHelper |
||||
{ |
||||
|
||||
/** |
||||
* @var array|null |
||||
*/ |
||||
protected $pageData; |
||||
|
||||
/** |
||||
* Initialize the helper and process available signed request data. |
||||
* |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
*/ |
||||
public function __construct($appId = null, $appSecret = null) |
||||
{ |
||||
parent::__construct($appId, $appSecret); |
||||
|
||||
if (!$this->signedRequest) { |
||||
return; |
||||
} |
||||
|
||||
$this->pageData = $this->signedRequest->get('page'); |
||||
} |
||||
|
||||
/** |
||||
* Returns a value from the page data. |
||||
* |
||||
* @param string $key |
||||
* @param mixed|null $default |
||||
* |
||||
* @return mixed|null |
||||
*/ |
||||
public function getPageData($key, $default = null) |
||||
{ |
||||
if (isset($this->pageData[$key])) { |
||||
return $this->pageData[$key]; |
||||
} |
||||
return $default; |
||||
} |
||||
|
||||
/** |
||||
* Returns true if the page is liked by the user. |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function isLiked() |
||||
{ |
||||
return $this->getPageData('liked') === true; |
||||
} |
||||
|
||||
/** |
||||
* Returns true if the user is an admin. |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function isAdmin() |
||||
{ |
||||
return $this->getPageData('admin') === true; |
||||
} |
||||
|
||||
/** |
||||
* Returns the page id if available. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getPageId() |
||||
{ |
||||
return $this->getPageData('id'); |
||||
} |
||||
|
||||
} |
@ -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; |
||||
|
||||
/** |
||||
* Class FacebookPermissionException |
||||
* @package Facebook |
||||
*/ |
||||
class FacebookPermissionException extends FacebookRequestException |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,324 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class FacebookRedirectLoginHelper |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class FacebookRedirectLoginHelper |
||||
{ |
||||
|
||||
/** |
||||
* @var string The application id |
||||
*/ |
||||
private $appId; |
||||
|
||||
/** |
||||
* @var string The application secret |
||||
*/ |
||||
private $appSecret; |
||||
|
||||
/** |
||||
* @var string The redirect URL for the application |
||||
*/ |
||||
private $redirectUrl; |
||||
|
||||
/** |
||||
* @var string Prefix to use for session variables |
||||
*/ |
||||
private $sessionPrefix = 'FBRLH_'; |
||||
|
||||
/** |
||||
* @var string State token for CSRF validation |
||||
*/ |
||||
protected $state; |
||||
|
||||
/** |
||||
* @var boolean Toggle for PHP session status check |
||||
*/ |
||||
protected $checkForSessionStatus = true; |
||||
|
||||
/** |
||||
* Constructs a RedirectLoginHelper for a given appId and redirectUrl. |
||||
* |
||||
* @param string $redirectUrl The URL Facebook should redirect users to |
||||
* after login |
||||
* @param string $appId The application id |
||||
* @param string $appSecret The application secret |
||||
*/ |
||||
public function __construct($redirectUrl, $appId = null, $appSecret = null) |
||||
{ |
||||
$this->appId = FacebookSession::_getTargetAppId($appId); |
||||
$this->appSecret = FacebookSession::_getTargetAppSecret($appSecret); |
||||
$this->redirectUrl = $redirectUrl; |
||||
} |
||||
|
||||
/** |
||||
* Stores CSRF state and returns a URL to which the user should be sent to |
||||
* in order to continue the login process with Facebook. The |
||||
* provided redirectUrl should invoke the handleRedirect method. |
||||
* |
||||
* @param array $scope List of permissions to request during login |
||||
* @param string $version Optional Graph API version if not default (v2.0) |
||||
* @param boolean $displayAsPopup Indicate if the page will be displayed as a popup |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getLoginUrl($scope = array(), $version = null, $displayAsPopup = false) |
||||
{ |
||||
|
||||
$version = ($version ?: FacebookRequest::GRAPH_API_VERSION); |
||||
$this->state = $this->random(16); |
||||
$this->storeState($this->state); |
||||
|
||||
$params = array( |
||||
'client_id' => $this->appId, |
||||
'redirect_uri' => $this->redirectUrl, |
||||
'state' => $this->state, |
||||
'sdk' => 'php-sdk-' . FacebookRequest::VERSION, |
||||
'scope' => implode(',', $scope) |
||||
); |
||||
|
||||
if ($displayAsPopup) |
||||
{ |
||||
$params['display'] = 'popup'; |
||||
} |
||||
|
||||
return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . |
||||
http_build_query($params, null, '&'); |
||||
} |
||||
|
||||
/** |
||||
* Returns a URL to which the user should be sent to re-request permissions. |
||||
* |
||||
* @param array $scope List of permissions to re-request |
||||
* @param string $version Optional Graph API version if not default (v2.0) |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getReRequestUrl($scope = array(), $version = null) |
||||
{ |
||||
$version = ($version ?: FacebookRequest::GRAPH_API_VERSION); |
||||
$this->state = $this->random(16); |
||||
$this->storeState($this->state); |
||||
$params = array( |
||||
'client_id' => $this->appId, |
||||
'redirect_uri' => $this->redirectUrl, |
||||
'state' => $this->state, |
||||
'sdk' => 'php-sdk-' . FacebookRequest::VERSION, |
||||
'auth_type' => 'rerequest', |
||||
'scope' => implode(',', $scope) |
||||
); |
||||
return 'https://www.facebook.com/' . $version . '/dialog/oauth?' . |
||||
http_build_query($params, null, '&'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the URL to send the user in order to log out of Facebook. |
||||
* |
||||
* @param FacebookSession $session The session that will be logged out |
||||
* @param string $next The url Facebook should redirect the user to after |
||||
* a successful logout |
||||
* |
||||
* @return string |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public function getLogoutUrl(FacebookSession $session, $next) |
||||
{ |
||||
if ($session->getAccessToken()->isAppSession()) { |
||||
throw new FacebookSDKException( |
||||
'Cannot generate a Logout URL with an App Session.', 722 |
||||
); |
||||
} |
||||
$params = array( |
||||
'next' => $next, |
||||
'access_token' => $session->getToken() |
||||
); |
||||
return 'https://www.facebook.com/logout.php?' . http_build_query($params, null, '&'); |
||||
} |
||||
|
||||
/** |
||||
* Handles a response from Facebook, including a CSRF check, and returns a |
||||
* FacebookSession. |
||||
* |
||||
* @return FacebookSession|null |
||||
*/ |
||||
public function getSessionFromRedirect() |
||||
{ |
||||
$this->loadState(); |
||||
if ($this->isValidRedirect()) { |
||||
|
||||
$params = array( |
||||
'client_id' => FacebookSession::_getTargetAppId($this->appId), |
||||
'redirect_uri' => $this->redirectUrl, |
||||
'client_secret' => |
||||
FacebookSession::_getTargetAppSecret($this->appSecret), |
||||
'code' => $this->getCode() |
||||
); |
||||
|
||||
$response = (new FacebookRequest( |
||||
FacebookSession::newAppSession($this->appId, $this->appSecret), |
||||
'GET', |
||||
'/oauth/access_token', |
||||
$params |
||||
))->execute()->getResponse(); |
||||
|
||||
if (isset($response['access_token'])) { |
||||
return new FacebookSession($response['access_token']); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Check if a redirect has a valid state. |
||||
* |
||||
* @return bool |
||||
*/ |
||||
protected function isValidRedirect() |
||||
{ |
||||
return $this->getCode() && isset($_GET['state']) |
||||
&& $_GET['state'] == $this->state; |
||||
} |
||||
|
||||
/** |
||||
* Return the code. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
protected function getCode() |
||||
{ |
||||
|
||||
return isset($_GET['code']) ? $_GET['code'] : null; |
||||
} |
||||
|
||||
/** |
||||
* Stores a state string in session storage for CSRF protection. |
||||
* Developers should subclass and override this method if they want to store |
||||
* this state in a different location. |
||||
* |
||||
* @param string $state |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
protected function storeState($state) |
||||
{ |
||||
if ($this->checkForSessionStatus === true |
||||
&& session_status() !== PHP_SESSION_ACTIVE) { |
||||
throw new FacebookSDKException( |
||||
'Session not active, could not store state.', 720 |
||||
); |
||||
} |
||||
$_SESSION[$this->sessionPrefix . 'state'] = $state; |
||||
} |
||||
|
||||
/** |
||||
* Loads a state string from session storage for CSRF validation. May return |
||||
* null if no object exists. Developers should subclass and override this |
||||
* method if they want to load the state from a different location. |
||||
* |
||||
* @return string|null |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
protected function loadState() |
||||
{ |
||||
|
||||
if ($this->checkForSessionStatus === true |
||||
&& session_status() !== PHP_SESSION_ACTIVE) { |
||||
throw new FacebookSDKException( |
||||
'Session not active, could not load state.', 721 |
||||
); |
||||
} |
||||
if (isset($_SESSION[$this->sessionPrefix . 'state'])) { |
||||
$this->state = $_SESSION[$this->sessionPrefix . 'state']; |
||||
return $this->state; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Generate a cryptographically secure pseudrandom number |
||||
* |
||||
* @param integer $bytes - number of bytes to return |
||||
* |
||||
* @return string |
||||
* |
||||
* @throws FacebookSDKException |
||||
* |
||||
* @todo Support Windows platforms |
||||
*/ |
||||
public function random($bytes) |
||||
{ |
||||
if (!is_numeric($bytes)) { |
||||
throw new FacebookSDKException( |
||||
"random() expects an integer" |
||||
); |
||||
} |
||||
if ($bytes < 1) { |
||||
throw new FacebookSDKException( |
||||
"random() expects an integer greater than zero" |
||||
); |
||||
} |
||||
$buf = ''; |
||||
// http://sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers/ |
||||
if (!ini_get('open_basedir') |
||||
&& is_readable('/dev/urandom')) { |
||||
$fp = fopen('/dev/urandom', 'rb'); |
||||
if ($fp !== FALSE) { |
||||
$buf = fread($fp, $bytes); |
||||
fclose($fp); |
||||
if($buf !== FALSE) { |
||||
return bin2hex($buf); |
||||
} |
||||
} |
||||
} |
||||
|
||||
if (function_exists('mcrypt_create_iv')) { |
||||
$buf = mcrypt_create_iv($bytes, MCRYPT_DEV_URANDOM); |
||||
if ($buf !== FALSE) { |
||||
return bin2hex($buf); |
||||
} |
||||
} |
||||
|
||||
while (strlen($buf) < $bytes) { |
||||
$buf .= md5(uniqid(mt_rand(), true), true); |
||||
// We are appending raw binary |
||||
} |
||||
return bin2hex(substr($buf, 0, $bytes)); |
||||
} |
||||
|
||||
/** |
||||
* Disables the session_status() check when using $_SESSION |
||||
*/ |
||||
public function disableSessionStatusCheck() |
||||
{ |
||||
$this->checkForSessionStatus = false; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,313 @@ |
||||
<?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\HttpClients\FacebookHttpable; |
||||
use Facebook\HttpClients\FacebookCurlHttpClient; |
||||
use Facebook\HttpClients\FacebookStreamHttpClient; |
||||
|
||||
/** |
||||
* Class FacebookRequest |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class FacebookRequest |
||||
{ |
||||
|
||||
/** |
||||
* @const string Version number of the Facebook PHP SDK. |
||||
*/ |
||||
const VERSION = '4.0.15'; |
||||
|
||||
/** |
||||
* @const string Default Graph API version for requests |
||||
*/ |
||||
const GRAPH_API_VERSION = 'v2.2'; |
||||
|
||||
/** |
||||
* @const string Graph API URL |
||||
*/ |
||||
const BASE_GRAPH_URL = 'https://graph.facebook.com'; |
||||
|
||||
/** |
||||
* @var FacebookSession The session used for this request |
||||
*/ |
||||
private $session; |
||||
|
||||
/** |
||||
* @var string The HTTP method for the request |
||||
*/ |
||||
private $method; |
||||
|
||||
/** |
||||
* @var string The path for the request |
||||
*/ |
||||
private $path; |
||||
|
||||
/** |
||||
* @var array The parameters for the request |
||||
*/ |
||||
private $params; |
||||
|
||||
/** |
||||
* @var string The Graph API version for the request |
||||
*/ |
||||
private $version; |
||||
|
||||
/** |
||||
* @var string ETag sent with the request |
||||
*/ |
||||
private $etag; |
||||
|
||||
/** |
||||
* @var FacebookHttpable HTTP client handler |
||||
*/ |
||||
private static $httpClientHandler; |
||||
|
||||
/** |
||||
* @var int The number of calls that have been made to Graph. |
||||
*/ |
||||
public static $requestCount = 0; |
||||
|
||||
/** |
||||
* getSession - Returns the associated FacebookSession. |
||||
* |
||||
* @return FacebookSession |
||||
*/ |
||||
public function getSession() |
||||
{ |
||||
return $this->session; |
||||
} |
||||
|
||||
/** |
||||
* getPath - Returns the associated path. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getPath() |
||||
{ |
||||
return $this->path; |
||||
} |
||||
|
||||
/** |
||||
* getParameters - Returns the associated parameters. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getParameters() |
||||
{ |
||||
return $this->params; |
||||
} |
||||
|
||||
/** |
||||
* getMethod - Returns the associated method. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getMethod() |
||||
{ |
||||
return $this->method; |
||||
} |
||||
|
||||
/** |
||||
* getETag - Returns the ETag sent with the request. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getETag() |
||||
{ |
||||
return $this->etag; |
||||
} |
||||
|
||||
/** |
||||
* setHttpClientHandler - Returns an instance of the HTTP client |
||||
* handler |
||||
* |
||||
* @param \Facebook\HttpClients\FacebookHttpable |
||||
*/ |
||||
public static function setHttpClientHandler(FacebookHttpable $handler) |
||||
{ |
||||
static::$httpClientHandler = $handler; |
||||
} |
||||
|
||||
/** |
||||
* getHttpClientHandler - Returns an instance of the HTTP client |
||||
* data handler |
||||
* |
||||
* @return FacebookHttpable |
||||
*/ |
||||
public static function getHttpClientHandler() |
||||
{ |
||||
if (static::$httpClientHandler) { |
||||
return static::$httpClientHandler; |
||||
} |
||||
return function_exists('curl_init') ? new FacebookCurlHttpClient() : new FacebookStreamHttpClient(); |
||||
} |
||||
|
||||
/** |
||||
* FacebookRequest - Returns a new request using the given session. optional |
||||
* parameters hash will be sent with the request. This object is |
||||
* immutable. |
||||
* |
||||
* @param FacebookSession $session |
||||
* @param string $method |
||||
* @param string $path |
||||
* @param array|null $parameters |
||||
* @param string|null $version |
||||
* @param string|null $etag |
||||
*/ |
||||
public function __construct( |
||||
FacebookSession $session, $method, $path, $parameters = null, $version = null, $etag = null |
||||
) |
||||
{ |
||||
$this->session = $session; |
||||
$this->method = $method; |
||||
$this->path = $path; |
||||
if ($version) { |
||||
$this->version = $version; |
||||
} else { |
||||
$this->version = static::GRAPH_API_VERSION; |
||||
} |
||||
$this->etag = $etag; |
||||
|
||||
$params = ($parameters ?: array()); |
||||
if ($session |
||||
&& !isset($params["access_token"])) { |
||||
$params["access_token"] = $session->getToken(); |
||||
} |
||||
if (FacebookSession::useAppSecretProof() |
||||
&& !isset($params["appsecret_proof"])) { |
||||
$params["appsecret_proof"] = $this->getAppSecretProof( |
||||
$params["access_token"] |
||||
); |
||||
} |
||||
$this->params = $params; |
||||
} |
||||
|
||||
/** |
||||
* Returns the base Graph URL. |
||||
* |
||||
* @return string |
||||
*/ |
||||
protected function getRequestURL() |
||||
{ |
||||
return static::BASE_GRAPH_URL . '/' . $this->version . $this->path; |
||||
} |
||||
|
||||
/** |
||||
* execute - Makes the request to Facebook and returns the result. |
||||
* |
||||
* @return FacebookResponse |
||||
* |
||||
* @throws FacebookSDKException |
||||
* @throws FacebookRequestException |
||||
*/ |
||||
public function execute() |
||||
{ |
||||
$url = $this->getRequestURL(); |
||||
$params = $this->getParameters(); |
||||
|
||||
if ($this->method === "GET") { |
||||
$url = self::appendParamsToUrl($url, $params); |
||||
$params = array(); |
||||
} |
||||
|
||||
$connection = self::getHttpClientHandler(); |
||||
$connection->addRequestHeader('User-Agent', 'fb-php-' . self::VERSION); |
||||
$connection->addRequestHeader('Accept-Encoding', '*'); // Support all available encodings. |
||||
|
||||
// ETag |
||||
if (isset($this->etag)) { |
||||
$connection->addRequestHeader('If-None-Match', $this->etag); |
||||
} |
||||
|
||||
// Should throw `FacebookSDKException` exception on HTTP client error. |
||||
// Don't catch to allow it to bubble up. |
||||
$result = $connection->send($url, $this->method, $params); |
||||
|
||||
static::$requestCount++; |
||||
|
||||
$etagHit = 304 == $connection->getResponseHttpStatusCode(); |
||||
|
||||
$headers = $connection->getResponseHeaders(); |
||||
$etagReceived = isset($headers['ETag']) ? $headers['ETag'] : null; |
||||
|
||||
$decodedResult = json_decode($result); |
||||
if ($decodedResult === null) { |
||||
$out = array(); |
||||
parse_str($result, $out); |
||||
return new FacebookResponse($this, $out, $result, $etagHit, $etagReceived); |
||||
} |
||||
if (isset($decodedResult->error)) { |
||||
throw FacebookRequestException::create( |
||||
$result, |
||||
$decodedResult->error, |
||||
$connection->getResponseHttpStatusCode() |
||||
); |
||||
} |
||||
|
||||
return new FacebookResponse($this, $decodedResult, $result, $etagHit, $etagReceived); |
||||
} |
||||
|
||||
/** |
||||
* Generate and return the appsecret_proof value for an access_token |
||||
* |
||||
* @param string $token |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getAppSecretProof($token) |
||||
{ |
||||
return hash_hmac('sha256', $token, FacebookSession::_getTargetAppSecret()); |
||||
} |
||||
|
||||
/** |
||||
* appendParamsToUrl - Gracefully appends params to the URL. |
||||
* |
||||
* @param string $url |
||||
* @param array $params |
||||
* |
||||
* @return string |
||||
*/ |
||||
public static function appendParamsToUrl($url, $params = array()) |
||||
{ |
||||
if (!$params) { |
||||
return $url; |
||||
} |
||||
|
||||
if (strpos($url, '?') === false) { |
||||
return $url . '?' . http_build_query($params, null, '&'); |
||||
} |
||||
|
||||
list($path, $query_string) = explode('?', $url, 2); |
||||
parse_str($query_string, $query_array); |
||||
|
||||
// Favor params from the original URL over $params |
||||
$params = array_merge($params, $query_array); |
||||
|
||||
return $path . '?' . http_build_query($params, null, '&'); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,222 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class FacebookRequestException |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class FacebookRequestException extends FacebookSDKException |
||||
{ |
||||
|
||||
/** |
||||
* @var int Status code for the response causing the exception |
||||
*/ |
||||
private $statusCode; |
||||
|
||||
/** |
||||
* @var string Raw response |
||||
*/ |
||||
private $rawResponse; |
||||
|
||||
/** |
||||
* @var array Decoded response |
||||
*/ |
||||
private $responseData; |
||||
|
||||
/** |
||||
* Creates a FacebookRequestException. |
||||
* |
||||
* @param string $rawResponse The raw response from the Graph API |
||||
* @param array $responseData The decoded response from the Graph API |
||||
* @param int $statusCode |
||||
*/ |
||||
public function __construct($rawResponse, $responseData, $statusCode) |
||||
{ |
||||
$this->rawResponse = $rawResponse; |
||||
$this->statusCode = $statusCode; |
||||
$this->responseData = self::convertToArray($responseData); |
||||
parent::__construct( |
||||
$this->get('message', 'Unknown Exception'), $this->get('code', -1), null |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* Process an error payload from the Graph API and return the appropriate |
||||
* exception subclass. |
||||
* |
||||
* @param string $raw the raw response from the Graph API |
||||
* @param array $data the decoded response from the Graph API |
||||
* @param int $statusCode the HTTP response code |
||||
* |
||||
* @return FacebookRequestException |
||||
*/ |
||||
public static function create($raw, $data, $statusCode) |
||||
{ |
||||
$data = self::convertToArray($data); |
||||
if (!isset($data['error']['code']) && isset($data['code'])) { |
||||
$data = array('error' => $data); |
||||
} |
||||
$code = (isset($data['error']['code']) ? $data['error']['code'] : 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 FacebookAuthorizationException($raw, $data, $statusCode); |
||||
break; |
||||
} |
||||
} |
||||
|
||||
switch ($code) { |
||||
// Login status or token expired, revoked, or invalid |
||||
case 100: |
||||
case 102: |
||||
case 190: |
||||
return new FacebookAuthorizationException($raw, $data, $statusCode); |
||||
break; |
||||
|
||||
// Server issue, possible downtime |
||||
case 1: |
||||
case 2: |
||||
return new FacebookServerException($raw, $data, $statusCode); |
||||
break; |
||||
|
||||
// API Throttling |
||||
case 4: |
||||
case 17: |
||||
case 341: |
||||
return new FacebookThrottleException($raw, $data, $statusCode); |
||||
break; |
||||
|
||||
// Duplicate Post |
||||
case 506: |
||||
return new FacebookClientException($raw, $data, $statusCode); |
||||
break; |
||||
} |
||||
|
||||
// Missing Permissions |
||||
if ($code == 10 || ($code >= 200 && $code <= 299)) { |
||||
return new FacebookPermissionException($raw, $data, $statusCode); |
||||
} |
||||
|
||||
// OAuth authentication error |
||||
if (isset($data['error']['type']) |
||||
and $data['error']['type'] === 'OAuthException') { |
||||
return new FacebookAuthorizationException($raw, $data, $statusCode); |
||||
} |
||||
|
||||
// All others |
||||
return new FacebookOtherException($raw, $data, $statusCode); |
||||
} |
||||
|
||||
/** |
||||
* 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->statusCode; |
||||
} |
||||
|
||||
/** |
||||
* 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->rawResponse; |
||||
} |
||||
|
||||
/** |
||||
* Returns the decoded response used to create the exception. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getResponse() |
||||
{ |
||||
return $this->responseData; |
||||
} |
||||
|
||||
/** |
||||
* Converts a stdClass object to an array |
||||
* |
||||
* @param mixed $object |
||||
* |
||||
* @return array |
||||
*/ |
||||
private static function convertToArray($object) |
||||
{ |
||||
if ($object instanceof \stdClass) { |
||||
return get_object_vars($object); |
||||
} |
||||
return $object; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,206 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class FacebookResponse |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class FacebookResponse |
||||
{ |
||||
|
||||
/** |
||||
* @var FacebookRequest The request which produced this response |
||||
*/ |
||||
private $request; |
||||
|
||||
/** |
||||
* @var array The decoded response from the Graph API |
||||
*/ |
||||
private $responseData; |
||||
|
||||
/** |
||||
* @var string The raw response from the Graph API |
||||
*/ |
||||
private $rawResponse; |
||||
|
||||
/** |
||||
* @var bool Indicates whether sent ETag matched the one on the FB side |
||||
*/ |
||||
private $etagHit; |
||||
|
||||
/** |
||||
* @var string ETag received with the response. `null` in case of ETag hit. |
||||
*/ |
||||
private $etag; |
||||
|
||||
/** |
||||
* Creates a FacebookResponse object for a given request and response. |
||||
* |
||||
* @param FacebookRequest $request |
||||
* @param array $responseData JSON Decoded response data |
||||
* @param string $rawResponse Raw string response |
||||
* @param bool $etagHit Indicates whether sent ETag matched the one on the FB side |
||||
* @param string|null $etag ETag received with the response. `null` in case of ETag hit. |
||||
*/ |
||||
public function __construct($request, $responseData, $rawResponse, $etagHit = false, $etag = null) |
||||
{ |
||||
$this->request = $request; |
||||
$this->responseData = $responseData; |
||||
$this->rawResponse = $rawResponse; |
||||
$this->etagHit = $etagHit; |
||||
$this->etag = $etag; |
||||
} |
||||
|
||||
/** |
||||
* Returns the request which produced this response. |
||||
* |
||||
* @return FacebookRequest |
||||
*/ |
||||
public function getRequest() |
||||
{ |
||||
return $this->request; |
||||
} |
||||
|
||||
/** |
||||
* Returns the decoded response data. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getResponse() |
||||
{ |
||||
return $this->responseData; |
||||
} |
||||
|
||||
/** |
||||
* Returns the raw response |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getRawResponse() |
||||
{ |
||||
return $this->rawResponse; |
||||
} |
||||
|
||||
/** |
||||
* Returns true if ETag matched the one sent with a request |
||||
* |
||||
* @return bool |
||||
*/ |
||||
public function isETagHit() |
||||
{ |
||||
return $this->etagHit; |
||||
} |
||||
|
||||
/** |
||||
* Returns the ETag |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getETag() |
||||
{ |
||||
return $this->etag; |
||||
} |
||||
|
||||
/** |
||||
* Gets the result as a GraphObject. If a type is specified, returns the |
||||
* strongly-typed subclass of GraphObject for the data. |
||||
* |
||||
* @param string $type |
||||
* |
||||
* @return mixed |
||||
*/ |
||||
public function getGraphObject($type = 'Facebook\GraphObject') { |
||||
return (new GraphObject($this->responseData))->cast($type); |
||||
} |
||||
|
||||
/** |
||||
* Returns an array of GraphObject returned by the request. If a type is |
||||
* specified, returns the strongly-typed subclass of GraphObject for the data. |
||||
* |
||||
* @param string $type |
||||
* |
||||
* @return mixed |
||||
*/ |
||||
public function getGraphObjectList($type = 'Facebook\GraphObject') { |
||||
$out = array(); |
||||
$data = $this->responseData->data; |
||||
$dataLength = count($data); |
||||
for ($i = 0; $i < $dataLength; $i++) { |
||||
$out[] = (new GraphObject($data[$i]))->cast($type); |
||||
} |
||||
return $out; |
||||
} |
||||
|
||||
/** |
||||
* If this response has paginated data, returns the FacebookRequest for the |
||||
* next page, or null. |
||||
* |
||||
* @return FacebookRequest|null |
||||
*/ |
||||
public function getRequestForNextPage() |
||||
{ |
||||
return $this->handlePagination('next'); |
||||
} |
||||
|
||||
/** |
||||
* If this response has paginated data, returns the FacebookRequest for the |
||||
* previous page, or null. |
||||
* |
||||
* @return FacebookRequest|null |
||||
*/ |
||||
public function getRequestForPreviousPage() |
||||
{ |
||||
return $this->handlePagination('previous'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the FacebookRequest for the previous or next page, or null. |
||||
* |
||||
* @param string $direction |
||||
* |
||||
* @return FacebookRequest|null |
||||
*/ |
||||
private function handlePagination($direction) { |
||||
if (isset($this->responseData->paging->$direction)) { |
||||
$url = parse_url($this->responseData->paging->$direction); |
||||
parse_str($url['query'], $params); |
||||
|
||||
if (isset($params['type']) && strpos($this->request->getPath(), $params['type']) !== false){ |
||||
unset($params['type']); |
||||
} |
||||
return new FacebookRequest( |
||||
$this->request->getSession(), |
||||
$this->request->getMethod(), |
||||
$this->request->getPath(), |
||||
$params |
||||
); |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
} |
@ -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; |
||||
|
||||
/** |
||||
* 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; |
||||
|
||||
/** |
||||
* Class FacebookServerException |
||||
* @package Facebook |
||||
*/ |
||||
class FacebookServerException extends FacebookRequestException |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,367 @@ |
||||
<?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\Entities\AccessToken; |
||||
use Facebook\Entities\SignedRequest; |
||||
|
||||
/** |
||||
* Class FacebookSession |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class FacebookSession |
||||
{ |
||||
|
||||
/** |
||||
* @var string |
||||
*/ |
||||
private static $defaultAppId; |
||||
|
||||
/** |
||||
* @var string |
||||
*/ |
||||
private static $defaultAppSecret; |
||||
|
||||
/** |
||||
* @var AccessToken The AccessToken entity for this connection. |
||||
*/ |
||||
private $accessToken; |
||||
|
||||
/** |
||||
* @var SignedRequest |
||||
*/ |
||||
private $signedRequest; |
||||
|
||||
/** |
||||
* @var bool |
||||
*/ |
||||
protected static $useAppSecretProof = true; |
||||
|
||||
/** |
||||
* When creating a Session from an access_token, use: |
||||
* var $session = new FacebookSession($accessToken); |
||||
* This will validate the token and provide a Session object ready for use. |
||||
* It will throw a SessionException in case of error. |
||||
* |
||||
* @param AccessToken|string $accessToken |
||||
* @param SignedRequest $signedRequest The SignedRequest entity |
||||
*/ |
||||
public function __construct($accessToken, SignedRequest $signedRequest = null) |
||||
{ |
||||
$this->accessToken = $accessToken instanceof AccessToken ? $accessToken : new AccessToken($accessToken); |
||||
$this->signedRequest = $signedRequest; |
||||
} |
||||
|
||||
/** |
||||
* Returns the access token. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getToken() |
||||
{ |
||||
return (string) $this->accessToken; |
||||
} |
||||
|
||||
/** |
||||
* Returns the access token entity. |
||||
* |
||||
* @return AccessToken |
||||
*/ |
||||
public function getAccessToken() |
||||
{ |
||||
return $this->accessToken; |
||||
} |
||||
|
||||
/** |
||||
* Returns the SignedRequest entity. |
||||
* |
||||
* @return SignedRequest |
||||
*/ |
||||
public function getSignedRequest() |
||||
{ |
||||
return $this->signedRequest; |
||||
} |
||||
|
||||
/** |
||||
* Returns the signed request payload. |
||||
* |
||||
* @return null|array |
||||
*/ |
||||
public function getSignedRequestData() |
||||
{ |
||||
return $this->signedRequest ? $this->signedRequest->getPayload() : null; |
||||
} |
||||
|
||||
/** |
||||
* Returns a property from the signed request data if available. |
||||
* |
||||
* @param string $key |
||||
* |
||||
* @return null|mixed |
||||
*/ |
||||
public function getSignedRequestProperty($key) |
||||
{ |
||||
return $this->signedRequest ? $this->signedRequest->get($key) : null; |
||||
} |
||||
|
||||
/** |
||||
* Returns user_id from signed request data if available. |
||||
* |
||||
* @return null|string |
||||
*/ |
||||
public function getUserId() |
||||
{ |
||||
return $this->signedRequest ? $this->signedRequest->getUserId() : null; |
||||
} |
||||
|
||||
// @TODO Remove getSessionInfo() in 4.1: can be accessed from AccessToken directly |
||||
/** |
||||
* getSessionInfo - Makes a request to /debug_token with the appropriate |
||||
* arguments to get debug information about the sessions token. |
||||
* |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return GraphSessionInfo |
||||
*/ |
||||
public function getSessionInfo($appId = null, $appSecret = null) |
||||
{ |
||||
return $this->accessToken->getInfo($appId, $appSecret); |
||||
} |
||||
|
||||
// @TODO Remove getLongLivedSession() in 4.1: can be accessed from AccessToken directly |
||||
/** |
||||
* getLongLivedSession - Returns a new Facebook session resulting from |
||||
* extending a short-lived access token. If this session is not |
||||
* short-lived, returns $this. |
||||
* |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return FacebookSession |
||||
*/ |
||||
public function getLongLivedSession($appId = null, $appSecret = null) |
||||
{ |
||||
$longLivedAccessToken = $this->accessToken->extend($appId, $appSecret); |
||||
return new static($longLivedAccessToken, $this->signedRequest); |
||||
} |
||||
|
||||
// @TODO Remove getExchangeToken() in 4.1: can be accessed from AccessToken directly |
||||
/** |
||||
* getExchangeToken - Returns an exchange token string which can be sent |
||||
* back to clients and exchanged for a device-linked access token. |
||||
* |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function getExchangeToken($appId = null, $appSecret = null) |
||||
{ |
||||
return AccessToken::getCodeFromAccessToken($this->accessToken, $appId, $appSecret); |
||||
} |
||||
|
||||
// @TODO Remove validate() in 4.1: can be accessed from AccessToken directly |
||||
/** |
||||
* validate - Ensures the current session is valid, throwing an exception if |
||||
* not. Fetches token info from Facebook. |
||||
* |
||||
* @param string|null $appId Application ID to use |
||||
* @param string|null $appSecret App secret value to use |
||||
* @param string|null $machineId |
||||
* |
||||
* @return boolean |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public function validate($appId = null, $appSecret = null, $machineId = null) |
||||
{ |
||||
if ($this->accessToken->isValid($appId, $appSecret, $machineId)) { |
||||
return true; |
||||
} |
||||
|
||||
// @TODO For v4.1 this should not throw an exception, but just return false. |
||||
throw new FacebookSDKException( |
||||
'Session has expired, or is not valid for this app.', 601 |
||||
); |
||||
} |
||||
|
||||
// @TODO Remove validateSessionInfo() in 4.1: can be accessed from AccessToken directly |
||||
/** |
||||
* validateTokenInfo - Ensures the provided GraphSessionInfo object is valid, |
||||
* throwing an exception if not. Ensures the appId matches, |
||||
* that the token is valid and has not expired. |
||||
* |
||||
* @param GraphSessionInfo $tokenInfo |
||||
* @param string|null $appId Application ID to use |
||||
* @param string|null $machineId |
||||
* |
||||
* @return boolean |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function validateSessionInfo(GraphSessionInfo $tokenInfo, |
||||
$appId = null, |
||||
$machineId = null) |
||||
{ |
||||
if (AccessToken::validateAccessToken($tokenInfo, $appId, $machineId)) { |
||||
return true; |
||||
} |
||||
|
||||
// @TODO For v4.1 this should not throw an exception, but just return false. |
||||
throw new FacebookSDKException( |
||||
'Session has expired, or is not valid for this app.', 601 |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* newSessionFromSignedRequest - Returns a FacebookSession for a |
||||
* given signed request. |
||||
* |
||||
* @param SignedRequest $signedRequest |
||||
* |
||||
* @return FacebookSession |
||||
*/ |
||||
public static function newSessionFromSignedRequest(SignedRequest $signedRequest) |
||||
{ |
||||
if ($signedRequest->get('code') |
||||
&& !$signedRequest->get('oauth_token')) { |
||||
return self::newSessionAfterValidation($signedRequest); |
||||
} |
||||
$accessToken = $signedRequest->get('oauth_token'); |
||||
$expiresAt = $signedRequest->get('expires', 0); |
||||
$accessToken = new AccessToken($accessToken, $expiresAt); |
||||
return new static($accessToken, $signedRequest); |
||||
} |
||||
|
||||
/** |
||||
* newSessionAfterValidation - Returns a FacebookSession for a |
||||
* validated & parsed signed request. |
||||
* |
||||
* @param SignedRequest $signedRequest |
||||
* |
||||
* @return FacebookSession |
||||
*/ |
||||
protected static function newSessionAfterValidation(SignedRequest $signedRequest) |
||||
{ |
||||
$code = $signedRequest->get('code'); |
||||
$accessToken = AccessToken::getAccessTokenFromCode($code); |
||||
return new static($accessToken, $signedRequest); |
||||
} |
||||
|
||||
/** |
||||
* newAppSession - Returns a FacebookSession configured with a token for the |
||||
* application which can be used for publishing and requesting app-level |
||||
* information. |
||||
* |
||||
* @param string|null $appId Application ID to use |
||||
* @param string|null $appSecret App secret value to use |
||||
* |
||||
* @return FacebookSession |
||||
*/ |
||||
public static function newAppSession($appId = null, $appSecret = null) |
||||
{ |
||||
$targetAppId = static::_getTargetAppId($appId); |
||||
$targetAppSecret = static::_getTargetAppSecret($appSecret); |
||||
return new FacebookSession( |
||||
$targetAppId . '|' . $targetAppSecret |
||||
); |
||||
} |
||||
|
||||
/** |
||||
* setDefaultApplication - Will set the static default appId and appSecret |
||||
* to be used for API requests. |
||||
* |
||||
* @param string $appId Application ID to use by default |
||||
* @param string $appSecret App secret value to use by default |
||||
*/ |
||||
public static function setDefaultApplication($appId, $appSecret) |
||||
{ |
||||
self::$defaultAppId = $appId; |
||||
self::$defaultAppSecret = $appSecret; |
||||
} |
||||
|
||||
/** |
||||
* _getTargetAppId - Will return either the provided app Id or the default, |
||||
* throwing if neither are populated. |
||||
* |
||||
* @param string $appId |
||||
* |
||||
* @return string |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function _getTargetAppId($appId = null) { |
||||
$target = ($appId ?: self::$defaultAppId); |
||||
if (!$target) { |
||||
throw new FacebookSDKException( |
||||
'You must provide or set a default application id.', 700 |
||||
); |
||||
} |
||||
return $target; |
||||
} |
||||
|
||||
/** |
||||
* _getTargetAppSecret - Will return either the provided app secret or the |
||||
* default, throwing if neither are populated. |
||||
* |
||||
* @param string $appSecret |
||||
* |
||||
* @return string |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public static function _getTargetAppSecret($appSecret = null) { |
||||
$target = ($appSecret ?: self::$defaultAppSecret); |
||||
if (!$target) { |
||||
throw new FacebookSDKException( |
||||
'You must provide or set a default application secret.', 701 |
||||
); |
||||
} |
||||
return $target; |
||||
} |
||||
|
||||
/** |
||||
* Enable or disable sending the appsecret_proof with requests. |
||||
* |
||||
* @param bool $on |
||||
*/ |
||||
public static function enableAppSecretProof($on = true) |
||||
{ |
||||
static::$useAppSecretProof = ($on ? true : false); |
||||
} |
||||
|
||||
/** |
||||
* Get whether or not appsecret_proof should be sent with requests. |
||||
* |
||||
* @return bool |
||||
*/ |
||||
public static function useAppSecretProof() |
||||
{ |
||||
return static::$useAppSecretProof; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,166 @@ |
||||
<?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\Entities\SignedRequest; |
||||
|
||||
/** |
||||
* Class FacebookSignedRequestFromInputHelper |
||||
* @package Facebook |
||||
*/ |
||||
abstract class FacebookSignedRequestFromInputHelper |
||||
{ |
||||
|
||||
/** |
||||
* @var \Facebook\Entities\SignedRequest|null |
||||
*/ |
||||
protected $signedRequest; |
||||
|
||||
/** |
||||
* @var string the app id |
||||
*/ |
||||
protected $appId; |
||||
|
||||
/** |
||||
* @var string the app secret |
||||
*/ |
||||
protected $appSecret; |
||||
|
||||
/** |
||||
* @var string|null Random string to prevent CSRF. |
||||
*/ |
||||
public $state = null; |
||||
|
||||
/** |
||||
* Initialize the helper and process available signed request data. |
||||
* |
||||
* @param string|null $appId |
||||
* @param string|null $appSecret |
||||
*/ |
||||
public function __construct($appId = null, $appSecret = null) |
||||
{ |
||||
$this->appId = FacebookSession::_getTargetAppId($appId); |
||||
$this->appSecret = FacebookSession::_getTargetAppSecret($appSecret); |
||||
|
||||
$this->instantiateSignedRequest(); |
||||
} |
||||
|
||||
/** |
||||
* Instantiates a new SignedRequest entity. |
||||
* |
||||
* @param string|null |
||||
*/ |
||||
public function instantiateSignedRequest($rawSignedRequest = null) |
||||
{ |
||||
$rawSignedRequest = $rawSignedRequest ?: $this->getRawSignedRequest(); |
||||
|
||||
if (!$rawSignedRequest) { |
||||
return; |
||||
} |
||||
|
||||
$this->signedRequest = new SignedRequest($rawSignedRequest, $this->state, $this->appSecret); |
||||
} |
||||
|
||||
/** |
||||
* Instantiates a FacebookSession from the signed request from input. |
||||
* |
||||
* @return FacebookSession|null |
||||
*/ |
||||
public function getSession() |
||||
{ |
||||
if ($this->signedRequest && $this->signedRequest->hasOAuthData()) { |
||||
return FacebookSession::newSessionFromSignedRequest($this->signedRequest); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Returns the SignedRequest entity. |
||||
* |
||||
* @return \Facebook\Entities\SignedRequest|null |
||||
*/ |
||||
public function getSignedRequest() |
||||
{ |
||||
return $this->signedRequest; |
||||
} |
||||
|
||||
/** |
||||
* Returns the user_id if available. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getUserId() |
||||
{ |
||||
return $this->signedRequest ? $this->signedRequest->getUserId() : null; |
||||
} |
||||
|
||||
/** |
||||
* Get raw signed request from input. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
abstract public function getRawSignedRequest(); |
||||
|
||||
/** |
||||
* Get raw signed request from GET input. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getRawSignedRequestFromGet() |
||||
{ |
||||
if (isset($_GET['signed_request'])) { |
||||
return $_GET['signed_request']; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Get raw signed request from POST input. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getRawSignedRequestFromPost() |
||||
{ |
||||
if (isset($_POST['signed_request'])) { |
||||
return $_POST['signed_request']; |
||||
} |
||||
|
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Get raw signed request from cookie set from the Javascript SDK. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getRawSignedRequestFromCookie() |
||||
{ |
||||
if (isset($_COOKIE['fbsr_' . $this->appId])) { |
||||
return $_COOKIE['fbsr_' . $this->appId]; |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
} |
@ -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; |
||||
|
||||
/** |
||||
* Class FacebookThrottleException |
||||
* @package Facebook |
||||
*/ |
||||
class FacebookThrottleException extends FacebookRequestException |
||||
{ |
||||
|
||||
} |
@ -0,0 +1,173 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class GraphAlbum |
||||
* @package Facebook |
||||
* @author Daniele Grosso <daniele.grosso@gmail.com> |
||||
*/ |
||||
|
||||
class GraphAlbum extends GraphObject |
||||
{ |
||||
/** |
||||
* Returns the ID for the album. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getId() |
||||
{ |
||||
return $this->getProperty('id'); |
||||
} |
||||
|
||||
/** |
||||
* Returns whether the viewer can upload photos to this album. |
||||
* |
||||
* @return boolean|null |
||||
*/ |
||||
public function canUpload() |
||||
{ |
||||
return $this->getProperty('can_upload'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the number of photos in this album. |
||||
* |
||||
* @return int|null |
||||
*/ |
||||
public function getCount() |
||||
{ |
||||
return $this->getProperty('count'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the ID of the album's cover photo. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getCoverPhoto() |
||||
{ |
||||
return $this->getProperty('cover_photo'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the time the album was initially created. |
||||
* |
||||
* @return \DateTime|null |
||||
*/ |
||||
public function getCreatedTime() |
||||
{ |
||||
$value = $this->getProperty('created_time'); |
||||
if ($value) { |
||||
return new \DateTime($value); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Returns the time the album was updated. |
||||
* |
||||
* @return \DateTime|null |
||||
*/ |
||||
public function getUpdatedTime() |
||||
{ |
||||
$value = $this->getProperty('updated_time'); |
||||
if ($value) { |
||||
return new \DateTime($value); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Returns the description of the album. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getDescription() |
||||
{ |
||||
return $this->getProperty('description'); |
||||
} |
||||
|
||||
/** |
||||
* Returns profile that created the album. |
||||
* |
||||
* @return GraphUser|null |
||||
*/ |
||||
public function getFrom() |
||||
{ |
||||
return $this->getProperty('from', GraphUser::className()); |
||||
} |
||||
|
||||
/** |
||||
* Returns a link to this album on Facebook. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getLink() |
||||
{ |
||||
return $this->getProperty('link'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the textual location of the album. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getLocation() |
||||
{ |
||||
return $this->getProperty('location'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the title of the album. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getName() |
||||
{ |
||||
return $this->getProperty('name'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the privacy settings for the album. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getPrivacy() |
||||
{ |
||||
return $this->getProperty('privacy'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the type of the album. enum{profile, mobile, wall, normal, album} |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getType() |
||||
{ |
||||
return $this->getProperty('type'); |
||||
} |
||||
|
||||
//TODO: public function getPlace() that should return GraphPage |
||||
} |
@ -0,0 +1,105 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class GraphLocation |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class GraphLocation extends GraphObject |
||||
{ |
||||
|
||||
/** |
||||
* Returns the street component of the location |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getStreet() |
||||
{ |
||||
return $this->getProperty('street'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the city component of the location |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getCity() |
||||
{ |
||||
return $this->getProperty('city'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the state component of the location |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getState() |
||||
{ |
||||
return $this->getProperty('state'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the country component of the location |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getCountry() |
||||
{ |
||||
return $this->getProperty('country'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the zipcode component of the location |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getZip() |
||||
{ |
||||
return $this->getProperty('zip'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the latitude component of the location |
||||
* |
||||
* @return float|null |
||||
*/ |
||||
public function getLatitude() |
||||
{ |
||||
return $this->getProperty('latitude'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the street component of the location |
||||
* |
||||
* @return float|null |
||||
*/ |
||||
public function getLongitude() |
||||
{ |
||||
return $this->getProperty('longitude'); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,171 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class GraphObject |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class GraphObject |
||||
{ |
||||
|
||||
/** |
||||
* @var array - Holds the raw associative data for this object |
||||
*/ |
||||
protected $backingData; |
||||
|
||||
/** |
||||
* Creates a GraphObject using the data provided. |
||||
* |
||||
* @param array $raw |
||||
*/ |
||||
public function __construct($raw) |
||||
{ |
||||
if ($raw instanceof \stdClass) { |
||||
$raw = get_object_vars($raw); |
||||
} |
||||
$this->backingData = $raw; |
||||
|
||||
if (isset($this->backingData['data']) && count($this->backingData) === 1) { |
||||
if ($this->backingData['data'] instanceof \stdClass) { |
||||
$this->backingData = get_object_vars($this->backingData['data']); |
||||
} else { |
||||
$this->backingData = $this->backingData['data']; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* cast - Return a new instance of a FacebookGraphObject subclass for this |
||||
* objects underlying data. |
||||
* |
||||
* @param string $type The GraphObject subclass to cast to |
||||
* |
||||
* @return GraphObject |
||||
* |
||||
* @throws FacebookSDKException |
||||
*/ |
||||
public function cast($type) |
||||
{ |
||||
if ($this instanceof $type) { |
||||
return $this; |
||||
} |
||||
if (is_subclass_of($type, GraphObject::className())) { |
||||
return new $type($this->backingData); |
||||
} else { |
||||
throw new FacebookSDKException( |
||||
'Cannot cast to an object that is not a GraphObject subclass', 620 |
||||
); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* asArray - Return a key-value associative array for the given graph object. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function asArray() |
||||
{ |
||||
return $this->backingData; |
||||
} |
||||
|
||||
/** |
||||
* getProperty - Gets the value of the named property for this graph object, |
||||
* cast to the appropriate subclass type if provided. |
||||
* |
||||
* @param string $name The property to retrieve |
||||
* @param string $type The subclass of GraphObject, optionally |
||||
* |
||||
* @return mixed |
||||
*/ |
||||
public function getProperty($name, $type = 'Facebook\GraphObject') |
||||
{ |
||||
if (isset($this->backingData[$name])) { |
||||
$value = $this->backingData[$name]; |
||||
if (is_scalar($value)) { |
||||
return $value; |
||||
} else { |
||||
return (new GraphObject($value))->cast($type); |
||||
} |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* getPropertyAsArray - Get the list value of a named property for this graph |
||||
* object, where each item has been cast to the appropriate subclass type |
||||
* if provided. |
||||
* |
||||
* Calling this for a property that is not an array, the behavior |
||||
* is undefined, so don’t do this. |
||||
* |
||||
* @param string $name The property to retrieve |
||||
* @param string $type The subclass of GraphObject, optionally |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getPropertyAsArray($name, $type = 'Facebook\GraphObject') |
||||
{ |
||||
$target = array(); |
||||
if (isset($this->backingData[$name]['data'])) { |
||||
$target = $this->backingData[$name]['data']; |
||||
} else if (isset($this->backingData[$name]) |
||||
&& !is_scalar($this->backingData[$name])) { |
||||
$target = $this->backingData[$name]; |
||||
} |
||||
$out = array(); |
||||
foreach ($target as $key => $value) { |
||||
if (is_scalar($value)) { |
||||
$out[$key] = $value; |
||||
} else { |
||||
$out[$key] = (new GraphObject($value))->cast($type); |
||||
} |
||||
} |
||||
return $out; |
||||
} |
||||
|
||||
/** |
||||
* getPropertyNames - Returns a list of all properties set on the object. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getPropertyNames() |
||||
{ |
||||
return array_keys($this->backingData); |
||||
} |
||||
|
||||
/** |
||||
* Returns the string class name of the GraphObject or subclass. |
||||
* |
||||
* @return string |
||||
*/ |
||||
public static function className() |
||||
{ |
||||
return get_called_class(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,64 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class GraphPage |
||||
* @package Facebook |
||||
* @author Artur Luiz <artur@arturluiz.com.br> |
||||
*/ |
||||
class GraphPage extends GraphObject |
||||
{ |
||||
|
||||
/** |
||||
* Returns the ID for the user's page as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getId() |
||||
{ |
||||
return $this->getProperty('id'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Category for the user's page as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getCategory() |
||||
{ |
||||
return $this->getProperty('category'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Name of the user's page as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getName() |
||||
{ |
||||
return $this->getProperty('name'); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,115 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class GraphSessionInfo |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class GraphSessionInfo extends GraphObject |
||||
{ |
||||
|
||||
/** |
||||
* Returns the application id the token was issued for. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getAppId() |
||||
{ |
||||
return $this->getProperty('app_id'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the application name the token was issued for. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getApplication() |
||||
{ |
||||
return $this->getProperty('application'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the date & time that the token expires. |
||||
* |
||||
* @return \DateTime|null |
||||
*/ |
||||
public function getExpiresAt() |
||||
{ |
||||
$stamp = $this->getProperty('expires_at'); |
||||
if ($stamp) { |
||||
return (new \DateTime())->setTimestamp($stamp); |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns whether the token is valid. |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
public function isValid() |
||||
{ |
||||
return $this->getProperty('is_valid'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the date & time the token was issued at. |
||||
* |
||||
* @return \DateTime|null |
||||
*/ |
||||
public function getIssuedAt() |
||||
{ |
||||
$stamp = $this->getProperty('issued_at'); |
||||
if ($stamp) { |
||||
return (new \DateTime())->setTimestamp($stamp); |
||||
} else { |
||||
return null; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns the scope permissions associated with the token. |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getScopes() |
||||
{ |
||||
return $this->getPropertyAsArray('scopes'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the login id of the user associated with the token. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getId() |
||||
{ |
||||
return $this->getProperty('user_id'); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,135 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class GraphUser |
||||
* @package Facebook |
||||
* @author Fosco Marotto <fjm@fb.com> |
||||
* @author David Poll <depoll@fb.com> |
||||
*/ |
||||
class GraphUser extends GraphObject |
||||
{ |
||||
|
||||
/** |
||||
* Returns the ID for the user as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getId() |
||||
{ |
||||
return $this->getProperty('id'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the name for the user as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getName() |
||||
{ |
||||
return $this->getProperty('name'); |
||||
} |
||||
|
||||
public function getEmail() |
||||
{ |
||||
return $this->getProperty('email'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the first name for the user as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getFirstName() |
||||
{ |
||||
return $this->getProperty('first_name'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the middle name for the user as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getMiddleName() |
||||
{ |
||||
return $this->getProperty('middle_name'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the last name for the user as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getLastName() |
||||
{ |
||||
return $this->getProperty('last_name'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the gender for the user as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getGender() |
||||
{ |
||||
return $this->getProperty('gender'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Facebook URL for the user as a string if available. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getLink() |
||||
{ |
||||
return $this->getProperty('link'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the users birthday, if available. |
||||
* |
||||
* @return \DateTime|null |
||||
*/ |
||||
public function getBirthday() |
||||
{ |
||||
$value = $this->getProperty('birthday'); |
||||
if ($value) { |
||||
return new \DateTime($value); |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* Returns the current location of the user as a FacebookGraphLocation |
||||
* if available. |
||||
* |
||||
* @return GraphLocation|null |
||||
*/ |
||||
public function getLocation() |
||||
{ |
||||
return $this->getProperty('location', GraphLocation::className()); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,84 @@ |
||||
<?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; |
||||
|
||||
/** |
||||
* Class GraphUserPage |
||||
* @package Facebook |
||||
* @author Artur Luiz <artur@arturluiz.com.br> |
||||
*/ |
||||
class GraphUserPage extends GraphObject |
||||
{ |
||||
|
||||
/** |
||||
* Returns the ID for the user's page as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getId() |
||||
{ |
||||
return $this->getProperty('id'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Category for the user's page as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getCategory() |
||||
{ |
||||
return $this->getProperty('category'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Name of the user's page as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getName() |
||||
{ |
||||
return $this->getProperty('name'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Access Token used to access the user's page as a string if present. |
||||
* |
||||
* @return string|null |
||||
*/ |
||||
public function getAccessToken() |
||||
{ |
||||
return $this->getProperty('access_token'); |
||||
} |
||||
|
||||
/** |
||||
* Returns the Permissions for the user's page as an array if present. |
||||
* |
||||
* @return array|null |
||||
*/ |
||||
public function getPermissions() |
||||
{ |
||||
return $this->getProperty('perms'); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,129 @@ |
||||
<?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\HttpClients; |
||||
|
||||
/** |
||||
* Class FacebookCurl |
||||
* Abstraction for the procedural curl elements so that curl can be mocked |
||||
* and the implementation can be tested. |
||||
* @package Facebook |
||||
*/ |
||||
class FacebookCurl |
||||
{ |
||||
|
||||
/** |
||||
* @var resource Curl resource instance |
||||
*/ |
||||
protected $curl; |
||||
|
||||
/** |
||||
* Make a new curl reference instance |
||||
*/ |
||||
public function init() |
||||
{ |
||||
$this->curl = curl_init(); |
||||
} |
||||
|
||||
/** |
||||
* Set a curl option |
||||
* |
||||
* @param $key |
||||
* @param $value |
||||
*/ |
||||
public function setopt($key, $value) |
||||
{ |
||||
curl_setopt($this->curl, $key, $value); |
||||
} |
||||
|
||||
/** |
||||
* Set an array of options to a curl resource |
||||
* |
||||
* @param array $options |
||||
*/ |
||||
public function setopt_array(array $options) |
||||
{ |
||||
curl_setopt_array($this->curl, $options); |
||||
} |
||||
|
||||
/** |
||||
* Send a curl request |
||||
* |
||||
* @return mixed |
||||
*/ |
||||
public function exec() |
||||
{ |
||||
return curl_exec($this->curl); |
||||
} |
||||
|
||||
/** |
||||
* Return the curl error number |
||||
* |
||||
* @return int |
||||
*/ |
||||
public function errno() |
||||
{ |
||||
return curl_errno($this->curl); |
||||
} |
||||
|
||||
/** |
||||
* Return the curl error message |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function error() |
||||
{ |
||||
return curl_error($this->curl); |
||||
} |
||||
|
||||
/** |
||||
* Get info from a curl reference |
||||
* |
||||
* @param $type |
||||
* |
||||
* @return mixed |
||||
*/ |
||||
public function getinfo($type) |
||||
{ |
||||
return curl_getinfo($this->curl, $type); |
||||
} |
||||
|
||||
/** |
||||
* Get the currently installed curl version |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function version() |
||||
{ |
||||
return curl_version(); |
||||
} |
||||
|
||||
/** |
||||
* Close the resource connection to curl |
||||
*/ |
||||
public function close() |
||||
{ |
||||
curl_close($this->curl); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,329 @@ |
||||
<?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\HttpClients; |
||||
|
||||
use Facebook\FacebookSDKException; |
||||
|
||||
/** |
||||
* Class FacebookCurlHttpClient |
||||
* @package Facebook |
||||
*/ |
||||
class FacebookCurlHttpClient implements FacebookHttpable |
||||
{ |
||||
|
||||
/** |
||||
* @var array The headers to be sent with the request |
||||
*/ |
||||
protected $requestHeaders = array(); |
||||
|
||||
/** |
||||
* @var array The headers received from the response |
||||
*/ |
||||
protected $responseHeaders = array(); |
||||
|
||||
/** |
||||
* @var int The HTTP status code returned from the server |
||||
*/ |
||||
protected $responseHttpStatusCode = 0; |
||||
|
||||
/** |
||||
* @var string The client error message |
||||
*/ |
||||
protected $curlErrorMessage = ''; |
||||
|
||||
/** |
||||
* @var int The curl client error code |
||||
*/ |
||||
protected $curlErrorCode = 0; |
||||
|
||||
/** |
||||
* @var string|boolean The raw response from the server |
||||
*/ |
||||
protected $rawResponse; |
||||
|
||||
/** |
||||
* @var FacebookCurl Procedural curl as object |
||||
*/ |
||||
protected static $facebookCurl; |
||||
|
||||
/** |
||||
* @var boolean If IPv6 should be disabled |
||||
*/ |
||||
protected static $disableIPv6; |
||||
|
||||
/** |
||||
* @const Curl Version which is unaffected by the proxy header length error. |
||||
*/ |
||||
const CURL_PROXY_QUIRK_VER = 0x071E00; |
||||
|
||||
/** |
||||
* @const "Connection Established" header text |
||||
*/ |
||||
const CONNECTION_ESTABLISHED = "HTTP/1.0 200 Connection established\r\n\r\n"; |
||||
|
||||
/** |
||||
* @param FacebookCurl|null Procedural curl as object |
||||
*/ |
||||
public function __construct(FacebookCurl $facebookCurl = null) |
||||
{ |
||||
self::$facebookCurl = $facebookCurl ?: new FacebookCurl(); |
||||
self::$disableIPv6 = self::$disableIPv6 ?: false; |
||||
} |
||||
|
||||
/** |
||||
* Disable IPv6 resolution |
||||
*/ |
||||
public function disableIPv6() |
||||
{ |
||||
self::$disableIPv6 = true; |
||||
} |
||||
|
||||
/** |
||||
* The headers we want to send with the request |
||||
* |
||||
* @param string $key |
||||
* @param string $value |
||||
*/ |
||||
public function addRequestHeader($key, $value) |
||||
{ |
||||
$this->requestHeaders[$key] = $value; |
||||
} |
||||
|
||||
/** |
||||
* The headers returned in the response |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getResponseHeaders() |
||||
{ |
||||
return $this->responseHeaders; |
||||
} |
||||
|
||||
/** |
||||
* The HTTP status response code |
||||
* |
||||
* @return int |
||||
*/ |
||||
public function getResponseHttpStatusCode() |
||||
{ |
||||
return $this->responseHttpStatusCode; |
||||
} |
||||
|
||||
/** |
||||
* Sends a request to the server |
||||
* |
||||
* @param string $url The endpoint to send the request to |
||||
* @param string $method The request method |
||||
* @param array $parameters The key value pairs to be sent in the body |
||||
* |
||||
* @return string Raw response from the server |
||||
* |
||||
* @throws \Facebook\FacebookSDKException |
||||
*/ |
||||
public function send($url, $method = 'GET', $parameters = array()) |
||||
{ |
||||
$this->openConnection($url, $method, $parameters); |
||||
$this->tryToSendRequest(); |
||||
|
||||
if ($this->curlErrorCode) { |
||||
throw new FacebookSDKException($this->curlErrorMessage, $this->curlErrorCode); |
||||
} |
||||
|
||||
// Separate the raw headers from the raw body |
||||
list($rawHeaders, $rawBody) = $this->extractResponseHeadersAndBody(); |
||||
|
||||
$this->responseHeaders = self::headersToArray($rawHeaders); |
||||
|
||||
$this->closeConnection(); |
||||
|
||||
return $rawBody; |
||||
} |
||||
|
||||
/** |
||||
* Opens a new curl connection |
||||
* |
||||
* @param string $url The endpoint to send the request to |
||||
* @param string $method The request method |
||||
* @param array $parameters The key value pairs to be sent in the body |
||||
*/ |
||||
public function openConnection($url, $method = 'GET', $parameters = array()) |
||||
{ |
||||
$options = array( |
||||
CURLOPT_URL => $url, |
||||
CURLOPT_CONNECTTIMEOUT => 10, |
||||
CURLOPT_TIMEOUT => 60, |
||||
CURLOPT_RETURNTRANSFER => true, // Follow 301 redirects |
||||
CURLOPT_HEADER => true, // Enable header processing |
||||
CURLOPT_SSL_VERIFYHOST => 2, |
||||
CURLOPT_SSL_VERIFYPEER => true, |
||||
CURLOPT_CAINFO => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', |
||||
); |
||||
|
||||
if ($method !== "GET") { |
||||
$options[CURLOPT_POSTFIELDS] = $parameters; |
||||
} |
||||
if ($method === 'DELETE' || $method === 'PUT') { |
||||
$options[CURLOPT_CUSTOMREQUEST] = $method; |
||||
} |
||||
|
||||
if (!empty($this->requestHeaders)) { |
||||
$options[CURLOPT_HTTPHEADER] = $this->compileRequestHeaders(); |
||||
} |
||||
|
||||
if (self::$disableIPv6) { |
||||
$options[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4; |
||||
} |
||||
|
||||
self::$facebookCurl->init(); |
||||
self::$facebookCurl->setopt_array($options); |
||||
} |
||||
|
||||
/** |
||||
* Closes an existing curl connection |
||||
*/ |
||||
public function closeConnection() |
||||
{ |
||||
self::$facebookCurl->close(); |
||||
} |
||||
|
||||
/** |
||||
* Try to send the request |
||||
*/ |
||||
public function tryToSendRequest() |
||||
{ |
||||
$this->sendRequest(); |
||||
$this->curlErrorMessage = self::$facebookCurl->error(); |
||||
$this->curlErrorCode = self::$facebookCurl->errno(); |
||||
$this->responseHttpStatusCode = self::$facebookCurl->getinfo(CURLINFO_HTTP_CODE); |
||||
} |
||||
|
||||
/** |
||||
* Send the request and get the raw response from curl |
||||
*/ |
||||
public function sendRequest() |
||||
{ |
||||
$this->rawResponse = self::$facebookCurl->exec(); |
||||
} |
||||
|
||||
/** |
||||
* Compiles the request headers into a curl-friendly format |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function compileRequestHeaders() |
||||
{ |
||||
$return = array(); |
||||
|
||||
foreach ($this->requestHeaders as $key => $value) { |
||||
$return[] = $key . ': ' . $value; |
||||
} |
||||
|
||||
return $return; |
||||
} |
||||
|
||||
/** |
||||
* Extracts the headers and the body into a two-part array |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function extractResponseHeadersAndBody() |
||||
{ |
||||
$headerSize = self::getHeaderSize(); |
||||
|
||||
$rawHeaders = mb_substr($this->rawResponse, 0, $headerSize); |
||||
$rawBody = mb_substr($this->rawResponse, $headerSize); |
||||
|
||||
return array(trim($rawHeaders), trim($rawBody)); |
||||
} |
||||
|
||||
/** |
||||
* Converts raw header responses into an array |
||||
* |
||||
* @param string $rawHeaders |
||||
* |
||||
* @return array |
||||
*/ |
||||
public static function headersToArray($rawHeaders) |
||||
{ |
||||
$headers = array(); |
||||
|
||||
// Normalize line breaks |
||||
$rawHeaders = str_replace("\r\n", "\n", $rawHeaders); |
||||
|
||||
// There will be multiple headers if a 301 was followed |
||||
// or a proxy was followed, etc |
||||
$headerCollection = explode("\n\n", trim($rawHeaders)); |
||||
// We just want the last response (at the end) |
||||
$rawHeader = array_pop($headerCollection); |
||||
|
||||
$headerComponents = explode("\n", $rawHeader); |
||||
foreach ($headerComponents as $line) { |
||||
if (strpos($line, ': ') === false) { |
||||
$headers['http_code'] = $line; |
||||
} else { |
||||
list ($key, $value) = explode(': ', $line); |
||||
$headers[$key] = $value; |
||||
} |
||||
} |
||||
|
||||
return $headers; |
||||
} |
||||
|
||||
/** |
||||
* Return proper header size |
||||
* |
||||
* @return integer |
||||
*/ |
||||
private function getHeaderSize() |
||||
{ |
||||
$headerSize = self::$facebookCurl->getinfo(CURLINFO_HEADER_SIZE); |
||||
// This corrects a Curl bug where header size does not account |
||||
// for additional Proxy headers. |
||||
if ( self::needsCurlProxyFix() ) { |
||||
// Additional way to calculate the request body size. |
||||
if (preg_match('/Content-Length: (\d+)/', $this->rawResponse, $m)) { |
||||
$headerSize = mb_strlen($this->rawResponse) - $m[1]; |
||||
} elseif (stripos($this->rawResponse, self::CONNECTION_ESTABLISHED) !== false) { |
||||
$headerSize += mb_strlen(self::CONNECTION_ESTABLISHED); |
||||
} |
||||
} |
||||
|
||||
return $headerSize; |
||||
} |
||||
|
||||
/** |
||||
* Detect versions of Curl which report incorrect header lengths when |
||||
* using Proxies. |
||||
* |
||||
* @return boolean |
||||
*/ |
||||
private static function needsCurlProxyFix() |
||||
{ |
||||
$ver = self::$facebookCurl->version(); |
||||
$version = $ver['version_number']; |
||||
|
||||
return $version < self::CURL_PROXY_QUIRK_VER; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,134 @@ |
||||
<?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\HttpClients; |
||||
|
||||
use Facebook\FacebookSDKException; |
||||
|
||||
use GuzzleHttp\Client; |
||||
use GuzzleHttp\Exception\AdapterException; |
||||
use GuzzleHttp\Exception\RequestException; |
||||
|
||||
class FacebookGuzzleHttpClient implements FacebookHttpable { |
||||
|
||||
/** |
||||
* @var array The headers to be sent with the request |
||||
*/ |
||||
protected $requestHeaders = array(); |
||||
|
||||
/** |
||||
* @var array The headers received from the response |
||||
*/ |
||||
protected $responseHeaders = array(); |
||||
|
||||
/** |
||||
* @var int The HTTP status code returned from the server |
||||
*/ |
||||
protected $responseHttpStatusCode = 0; |
||||
|
||||
/** |
||||
* @var \GuzzleHttp\Client The Guzzle client |
||||
*/ |
||||
protected static $guzzleClient; |
||||
|
||||
/** |
||||
* @param \GuzzleHttp\Client|null The Guzzle client |
||||
*/ |
||||
public function __construct(Client $guzzleClient = null) |
||||
{ |
||||
self::$guzzleClient = $guzzleClient ?: new Client(); |
||||
} |
||||
|
||||
/** |
||||
* The headers we want to send with the request |
||||
* |
||||
* @param string $key |
||||
* @param string $value |
||||
*/ |
||||
public function addRequestHeader($key, $value) |
||||
{ |
||||
$this->requestHeaders[$key] = $value; |
||||
} |
||||
|
||||
/** |
||||
* The headers returned in the response |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getResponseHeaders() |
||||
{ |
||||
return $this->responseHeaders; |
||||
} |
||||
|
||||
/** |
||||
* The HTTP status response code |
||||
* |
||||
* @return int |
||||
*/ |
||||
public function getResponseHttpStatusCode() |
||||
{ |
||||
return $this->responseHttpStatusCode; |
||||
} |
||||
|
||||
/** |
||||
* Sends a request to the server |
||||
* |
||||
* @param string $url The endpoint to send the request to |
||||
* @param string $method The request method |
||||
* @param array $parameters The key value pairs to be sent in the body |
||||
* |
||||
* @return string Raw response from the server |
||||
* |
||||
* @throws \Facebook\FacebookSDKException |
||||
*/ |
||||
public function send($url, $method = 'GET', $parameters = array()) |
||||
{ |
||||
$options = array(); |
||||
if ($parameters) { |
||||
$options = array('body' => $parameters); |
||||
} |
||||
|
||||
$options['verify'] = __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem'; |
||||
|
||||
$request = self::$guzzleClient->createRequest($method, $url, $options); |
||||
|
||||
foreach($this->requestHeaders as $k => $v) { |
||||
$request->setHeader($k, $v); |
||||
} |
||||
|
||||
try { |
||||
$rawResponse = self::$guzzleClient->send($request); |
||||
} catch (RequestException $e) { |
||||
if ($e->getPrevious() instanceof AdapterException) { |
||||
throw new FacebookSDKException($e->getMessage(), $e->getCode()); |
||||
} |
||||
$rawResponse = $e->getResponse(); |
||||
} |
||||
|
||||
$this->responseHttpStatusCode = $rawResponse->getStatusCode(); |
||||
$this->responseHeaders = $rawResponse->getHeaders(); |
||||
|
||||
return $rawResponse->getBody(); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,68 @@ |
||||
<?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\HttpClients; |
||||
|
||||
/** |
||||
* Interface FacebookHttpable |
||||
* @package Facebook |
||||
*/ |
||||
interface FacebookHttpable |
||||
{ |
||||
|
||||
/** |
||||
* The headers we want to send with the request |
||||
* |
||||
* @param string $key |
||||
* @param string $value |
||||
*/ |
||||
public function addRequestHeader($key, $value); |
||||
|
||||
/** |
||||
* The headers returned in the response |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getResponseHeaders(); |
||||
|
||||
/** |
||||
* The HTTP status response code |
||||
* |
||||
* @return int |
||||
*/ |
||||
public function getResponseHttpStatusCode(); |
||||
|
||||
/** |
||||
* Sends a request to the server |
||||
* |
||||
* @param string $url The endpoint to send the request to |
||||
* @param string $method The request method |
||||
* @param array $parameters The key value pairs to be sent in the body |
||||
* |
||||
* @return string Raw response from the server |
||||
* |
||||
* @throws \Facebook\FacebookSDKException |
||||
*/ |
||||
public function send($url, $method = 'GET', $parameters = array()); |
||||
|
||||
} |
@ -0,0 +1,79 @@ |
||||
<?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\HttpClients; |
||||
|
||||
/** |
||||
* Class FacebookStream |
||||
* Abstraction for the procedural stream elements so that the functions can be |
||||
* mocked and the implementation can be tested. |
||||
* @package Facebook |
||||
*/ |
||||
class FacebookStream |
||||
{ |
||||
|
||||
/** |
||||
* @var resource Context stream resource instance |
||||
*/ |
||||
protected $stream; |
||||
|
||||
/** |
||||
* @var array Response headers from the stream wrapper |
||||
*/ |
||||
protected $responseHeaders; |
||||
|
||||
/** |
||||
* Make a new context stream reference instance |
||||
* |
||||
* @param array $options |
||||
*/ |
||||
public function streamContextCreate(array $options) |
||||
{ |
||||
$this->stream = stream_context_create($options); |
||||
} |
||||
|
||||
/** |
||||
* The response headers from the stream wrapper |
||||
* |
||||
* @return array|null |
||||
*/ |
||||
public function getResponseHeaders() |
||||
{ |
||||
return $this->responseHeaders; |
||||
} |
||||
|
||||
/** |
||||
* Send a stream wrapped request |
||||
* |
||||
* @param string $url |
||||
* |
||||
* @return mixed |
||||
*/ |
||||
public function fileGetContents($url) |
||||
{ |
||||
$rawResponse = file_get_contents($url, false, $this->stream); |
||||
$this->responseHeaders = $http_response_header; |
||||
return $rawResponse; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,190 @@ |
||||
<?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\HttpClients; |
||||
|
||||
use Facebook\FacebookSDKException; |
||||
|
||||
class FacebookStreamHttpClient implements FacebookHttpable { |
||||
|
||||
/** |
||||
* @var array The headers to be sent with the request |
||||
*/ |
||||
protected $requestHeaders = array(); |
||||
|
||||
/** |
||||
* @var array The headers received from the response |
||||
*/ |
||||
protected $responseHeaders = array(); |
||||
|
||||
/** |
||||
* @var int The HTTP status code returned from the server |
||||
*/ |
||||
protected $responseHttpStatusCode = 0; |
||||
|
||||
/** |
||||
* @var FacebookStream Procedural stream wrapper as object |
||||
*/ |
||||
protected static $facebookStream; |
||||
|
||||
/** |
||||
* @param FacebookStream|null Procedural stream wrapper as object |
||||
*/ |
||||
public function __construct(FacebookStream $facebookStream = null) |
||||
{ |
||||
self::$facebookStream = $facebookStream ?: new FacebookStream(); |
||||
} |
||||
|
||||
/** |
||||
* The headers we want to send with the request |
||||
* |
||||
* @param string $key |
||||
* @param string $value |
||||
*/ |
||||
public function addRequestHeader($key, $value) |
||||
{ |
||||
$this->requestHeaders[$key] = $value; |
||||
} |
||||
|
||||
/** |
||||
* The headers returned in the response |
||||
* |
||||
* @return array |
||||
*/ |
||||
public function getResponseHeaders() |
||||
{ |
||||
return $this->responseHeaders; |
||||
} |
||||
|
||||
/** |
||||
* The HTTP status response code |
||||
* |
||||
* @return int |
||||
*/ |
||||
public function getResponseHttpStatusCode() |
||||
{ |
||||
return $this->responseHttpStatusCode; |
||||
} |
||||
|
||||
/** |
||||
* Sends a request to the server |
||||
* |
||||
* @param string $url The endpoint to send the request to |
||||
* @param string $method The request method |
||||
* @param array $parameters The key value pairs to be sent in the body |
||||
* |
||||
* @return string Raw response from the server |
||||
* |
||||
* @throws \Facebook\FacebookSDKException |
||||
*/ |
||||
public function send($url, $method = 'GET', $parameters = array()) |
||||
{ |
||||
$options = array( |
||||
'http' => array( |
||||
'method' => $method, |
||||
'timeout' => 60, |
||||
'ignore_errors' => true |
||||
), |
||||
'ssl' => array( |
||||
'verify_peer' => true, |
||||
'verify_peer_name' => true, |
||||
'allow_self_signed' => true, // All root certificates are self-signed |
||||
'cafile' => __DIR__ . '/certs/DigiCertHighAssuranceEVRootCA.pem', |
||||
), |
||||
); |
||||
|
||||
if ($parameters) { |
||||
$options['http']['content'] = http_build_query($parameters, null, '&'); |
||||
|
||||
$this->addRequestHeader('Content-type', 'application/x-www-form-urlencoded'); |
||||
} |
||||
|
||||
$options['http']['header'] = $this->compileHeader(); |
||||
|
||||
self::$facebookStream->streamContextCreate($options); |
||||
$rawResponse = self::$facebookStream->fileGetContents($url); |
||||
$rawHeaders = self::$facebookStream->getResponseHeaders(); |
||||
|
||||
if ($rawResponse === false || !$rawHeaders) { |
||||
throw new FacebookSDKException('Stream returned an empty response', 660); |
||||
} |
||||
|
||||
$this->responseHeaders = self::formatHeadersToArray($rawHeaders); |
||||
$this->responseHttpStatusCode = self::getStatusCodeFromHeader($this->responseHeaders['http_code']); |
||||
|
||||
return $rawResponse; |
||||
} |
||||
|
||||
/** |
||||
* Formats the headers for use in the stream wrapper |
||||
* |
||||
* @return string |
||||
*/ |
||||
public function compileHeader() |
||||
{ |
||||
$header = []; |
||||
foreach($this->requestHeaders as $k => $v) { |
||||
$header[] = $k . ': ' . $v; |
||||
} |
||||
|
||||
return implode("\r\n", $header); |
||||
} |
||||
|
||||
/** |
||||
* Converts array of headers returned from the wrapper into |
||||
* something standard |
||||
* |
||||
* @param array $rawHeaders |
||||
* |
||||
* @return array |
||||
*/ |
||||
public static function formatHeadersToArray(array $rawHeaders) |
||||
{ |
||||
$headers = array(); |
||||
|
||||
foreach ($rawHeaders as $line) { |
||||
if (strpos($line, ':') === false) { |
||||
$headers['http_code'] = $line; |
||||
} else { |
||||
list ($key, $value) = explode(': ', $line); |
||||
$headers[$key] = $value; |
||||
} |
||||
} |
||||
|
||||
return $headers; |
||||
} |
||||
|
||||
/** |
||||
* Pulls out the HTTP status code from a response header |
||||
* |
||||
* @param string $header |
||||
* |
||||
* @return int |
||||
*/ |
||||
public static function getStatusCodeFromHeader($header) |
||||
{ |
||||
preg_match('|HTTP/\d\.\d\s+(\d+)\s+.*|', $header, $match); |
||||
return (int) $match[1]; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,23 @@ |
||||
-----BEGIN CERTIFICATE----- |
||||
MIIDxTCCAq2gAwIBAgIQAqxcJmoLQJuPC3nyrkYldzANBgkqhkiG9w0BAQUFADBs |
||||
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 |
||||
d3cuZGlnaWNlcnQuY29tMSswKQYDVQQDEyJEaWdpQ2VydCBIaWdoIEFzc3VyYW5j |
||||
ZSBFViBSb290IENBMB4XDTA2MTExMDAwMDAwMFoXDTMxMTExMDAwMDAwMFowbDEL |
||||
MAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3 |
||||
LmRpZ2ljZXJ0LmNvbTErMCkGA1UEAxMiRGlnaUNlcnQgSGlnaCBBc3N1cmFuY2Ug |
||||
RVYgUm9vdCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMbM5XPm |
||||
+9S75S0tMqbf5YE/yc0lSbZxKsPVlDRnogocsF9ppkCxxLeyj9CYpKlBWTrT3JTW |
||||
PNt0OKRKzE0lgvdKpVMSOO7zSW1xkX5jtqumX8OkhPhPYlG++MXs2ziS4wblCJEM |
||||
xChBVfvLWokVfnHoNb9Ncgk9vjo4UFt3MRuNs8ckRZqnrG0AFFoEt7oT61EKmEFB |
||||
Ik5lYYeBQVCmeVyJ3hlKV9Uu5l0cUyx+mM0aBhakaHPQNAQTXKFx01p8VdteZOE3 |
||||
hzBWBOURtCmAEvF5OYiiAhF8J2a3iLd48soKqDirCmTCv2ZdlYTBoSUeh10aUAsg |
||||
EsxBu24LUTi4S8sCAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQF |
||||
MAMBAf8wHQYDVR0OBBYEFLE+w2kD+L9HAdSYJhoIAu9jZCvDMB8GA1UdIwQYMBaA |
||||
FLE+w2kD+L9HAdSYJhoIAu9jZCvDMA0GCSqGSIb3DQEBBQUAA4IBAQAcGgaX3Nec |
||||
nzyIZgYIVyHbIUf4KmeqvxgydkAQV8GK83rZEWWONfqe/EW1ntlMMUu4kehDLI6z |
||||
eM7b41N5cdblIZQB2lWHmiRk9opmzN6cN82oNLFpmyPInngiK3BD41VHMWEZ71jF |
||||
hS9OMPagMRYjyOfiZRYzy78aG6A9+MpeizGLYAiJLQwGXFK3xPkKmNEVX58Svnw2 |
||||
Yzi9RKR/5CYrCsSXaQ3pjOLAEFe4yHYSkVXySGnYvCoCWw9E1CAx2/S6cCZdkGCe |
||||
vEsXCS+0yx5DaMkHJ8HSXPfqIbloEpw8nL+e/IBcm2PN7EeqJSdnoDfzAIJ9VNep |
||||
+OkuE6N36B9K |
||||
-----END CERTIFICATE----- |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
@ -1,7 +1,5 @@ |
||||
{% if add_facebook_login_button.show_message %} |
||||
<div class="well"> |
||||
<a href="{{add_facebook_login_button.facebook_href_link}}"> |
||||
<img src="{{add_facebook_login_button.facebook_button_url}}"/> |
||||
</a> |
||||
</div> |
||||
<a href="{{add_facebook_login_button.facebook_href_link}}"> |
||||
<img src="{{add_facebook_login_button.facebook_button_url}}" style="margin-left:15px; border-radius:0"/> |
||||
</a> |
||||
{% endif %} |
||||
|
Loading…
Reference in new issue