Skip to content

Instantly share code, notes, and snippets.

@geeksunny
Last active December 10, 2015 20:28
Show Gist options
  • Save geeksunny/4488142 to your computer and use it in GitHub Desktop.
Save geeksunny/4488142 to your computer and use it in GitHub Desktop.
A simple class for interfacing with the Facebook API.
<?php
/* // EXAMPLE CODE!!!
error_reporting("E_ALL");
ini_set('display_errors', '1');
//session_start();$_SESSION = '';var_dump($_SESSION);die; // RESET SESSION
// Facebook App credentials
$app_id = "xxxxxxxxxxxxxxx";
$app_secret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
$my_url = "http://xxx.xxx.xxx/xxx.xxx";
//$my_url = false;
$permissions = array('email','user_work_history');
// Connecting to facebook!
$fb = new facebook_connect($app_id, $app_secret, $my_url);
$authed = $fb->auth($permissions);
if ($authed) {
$user = array(
$fb->parse_field('first_name'),
$fb->parse_field('last_name'),
$fb->parse_field('location','name'),
$fb->parse_field('email')
);
echo "user: ";
var_dump($user);
} else {
echo 'There was an error polling the Facebook API.';
var_dump($fb->get_error());
echo '<br><br>';
var_dump($_SESSION);
}
*/
class facebook_connect {
// Toggleable CSRF checking (Read: State checking & validation)
// To turn this off, set it to false. Should only be necessary if your users might have cookies disabled in their browser.
public $check_session = true;
// Facebook configuration variables
private $app_id;
private $app_secret;
private $redirect_url;
// Facebook API auth variables
private $code;
private $token;
// Error variables
private $error;
private $error_reason;
private $error_description;
private $error_origin;
// Facebook data
public $user_data;
// Class constructor: sets all required parameters for the Facebook API.
public function __construct($app_id, $app_secret, $redirect_url = false) {
// Start the session if not yet available.
if (!isset($_SESSION)) {
session_start();
}
// Set the required variables
$this->app_id = $app_id;
$this->app_secret = $app_secret;
// Set redirect URL
if ($redirect_url) {
$this->redirect_url = $redirect_url;
} else {
// If no redirect URL is provided, grab the current browser URL.
$pageURL = (@$_SERVER["HTTPS"] == "on") ? "https://" : "http://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"]/*.$_SERVER["REQUEST_URI"]*/;
}
$this->redirect_url = $pageURL;
}
}
// auth: Grabs authentication status with Facebook API. Redirects if no token is currently set.
// Parameter $permissions: Accepts an array of values for which extra permissions might be requested.
// Permissions list: https://developers.facebook.com/docs/reference/login/user-friend-permissions/
public function auth($permissions = array()) {
// Grabbing variables from URL
$this->code = $_REQUEST["code"];
$this->error = $_REQUEST["error"];
// If neither code nor error are set, forward to the Facebook sign-in / permission checking page.
if(!isset($this->code) && !isset($this->error)) {
// Creating redirect URL for connecting to Facebook.
$_SESSION['state'] = md5(uniqid(rand(), TRUE)); // CSRF protection
$dialog_url = "https://www.facebook.com/dialog/oauth?client_id="
. $this->app_id . "&redirect_uri=" . urlencode($this->redirect_url) . "&state="
. $_SESSION['state'];
// Appending the permissions list to the URL if one is available.
if (is_array($permissions) && $perm_string = implode(',',$permissions)) {
$dialog_url .= "&scope=$perm_string";
}
// Redirecting to Facebook.
if (!headers_sent()) {
// If no headers have been sent, perform a 302 browser redirect.
header("Location: ".$dialog_url);
exit;
} else {
// Else, redirect via javascript
echo("<script> top.location.href='" . $dialog_url . "'</script>");
}
//exit; // Kill the script for good measure.
}
// If code is set, request a token from Facebook.
elseif (isset($this->code)) {
// Checking our session state, for security purposes.
if (($_SESSION['state'] && ($_SESSION['state'] === $_REQUEST['state'])) || ($this->check_session === false)) {
if (!$this->init_token()) {
$this->error = 'auth error';
$this->error_reason ='token creation';
$this->error_description = "The API token could not be created.";
$this->error_origin = 'class';
return false;
} else {
return true;
}
}
else {
$this->error = 'auth error';
$this->error_reason ='state mismatch';
$this->error_description = "The state does not match. You may be a victim of CSRF.";
$this->error_origin = 'class';
return false;
}
}
// Otherwise, we have an error.
else {
/* //Error response URL autodirect
YOUR_REDIRECT_URI?
error_reason=user_denied
&error=access_denied
&error_description=The+user+denied+your+request.
&state=YOUR_STATE_VALUE
*/
$this->error_reason = urldecode($_REQUEST["error_reason"]);
$this->error_description = urldecode($_REQUEST["error_description"]);
$this->error_origin = 'api';
// https://developers.facebook.com/docs/howtos/login/handling-revoked-permissions/
return false;
}
}
// Init token: Grab the token from the session if its set, otherwise request a fresh one from Facebook.
private function init_token() {
if (!isset($_SESSION['access_token'])) {
// Grabbing a new token from Facebook!
// Exchanging the code for an access token
$token_url = "https://graph.facebook.com/oauth/access_token";
$token_string = "client_id=" . $this->app_id . "&redirect_uri=" . urlencode($this->redirect_url)
. "&client_secret=" . $this->app_secret . "&code=" . $this->code;
$response = $this->curl_post($token_url,$token_string,'get');
$params = null;
parse_str($response, $params);
$_SESSION['access_token'] = $params['access_token'];
}
// Setting the token in the class object.
return ($this->token = $_SESSION['access_token']) ? true : false;
}
// Get Error: Returns an array of any current error messages, or false if there is none
public function get_error() {
return (isset($this->error)) ? array('error'=>$this->error,'error_reason'=>$this->error_reason,'error_description'=>$this->error_description,'error_origin'=>$this->error_origin) : false;
}
/* ----- Facebook Info Polling functions ----- */
// Poll All: Populates $this->user_data with an associative array of ALL available data from Facebook.
public function poll_all() {
$graph_url = "https://graph.facebook.com/me";
$graph_string = "access_token=".$this->token;
return ($this->user_data = json_decode($this->curl_post($graph_url,$graph_string,'get'), true)) ? true : false;
}
/* ----- Facebook Info Parsing functions ----- */
// Parse All: Returns a copy of the entire contents of $this->user_data.
// Returns false if user data cannot be obtained.
public function parse_all() {
if (!isset($this->user_data)) {
$this->poll_all();
}
return (isset($this->user_data)) ? $this->user_data : false;
}
// Parse Keys: Returns an array all available data keys in the $this->user_data associative array.
// If $field is set, the function will return all keys beneath the given field if it is an array.
// Returns false if user data cannot be obtained.
public function parse_keys($field = false) {
if (!isset($this->user_data)) {
$this->poll_all();
}
//$target = ($field) ? &$this->user_data[$field] : &$this->user_data;
if ($field) {
$target = &$this->user_data[$field];
} else {
$target = &$this->user_data;
}
return (is_array($target)) ? array_keys($target) : false;
}
// Parse Field: Parse the Facebook user data for the given field name and returns a copy of the value.
// Pass in the array key you'd like to grab. Multiple keys (individually) for multiple levels of depth.
// ex. ('location','name') for $this->user_data['location']['name']
// If no argument is passed, $this->parse_all() is ran and returned.
// Returns false if field value is not found.
public function parse_field() {
if (func_num_args() == 0)
return $this->parse_all();
if (!isset($this->user_data)) {
$this->poll_all();
}
$arg_list = func_get_args();
$target = &$this->user_data;
foreach ($arg_list as $arg) {
$target = &$target[$arg];
}
return (isset($target)) ? $target : false;
}
/* ----- Misc functions ----- */
private function curl_post($url, $post_string, $method = 'post')
{
$ch = curl_init();
if($method == 'get')
{
curl_setopt($ch, CURLOPT_URL, $url. '?' . $post_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
if(preg_match("/https/", $url)){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
}
}
else
{ //default to 'post'
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
if(preg_match("/https/", $url)){
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
}
}
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment