commit
						f5ab4944aa
					
				@ -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}}"/> | 
				
			||||
    <img src="{{add_facebook_login_button.facebook_button_url}}" style="margin-left:15px; border-radius:0"/> | 
				
			||||
</a> | 
				
			||||
    </div> | 
				
			||||
{% endif %} | 
				
			||||
 | 
				
			||||
					Loading…
					
					
				
		Reference in new issue