Release 1.2.4 --- code refactoring, add new api reAuthorizeApplication

<?php
/**
* A facebook application framework
*/
class AppData{
    private
$data;

    public static function
getInstance(){
        static
$instance;
        if(!isset(
$instance)){
           
$class_name = __CLASS__;
           
$instance = new $class_name();
        }
        return
$instance;
    }

    public function
__construct(){
       
$this->data = array(   
           
"application_id" => "[your application id]",
       
"application_secret" => "[your application secret]",
           
"canvas_page_url" => "[your canvas page url]",
           
"connect_url" => "[your connect url]",
           
"datastore_type" => "memcache",
           
"memcache_servers" => array(
               
"server_1" => array( "host" => "127.0.0.1", "port" => "11211"),
            ),
        );
    }

    public function
get($key){
        if(
array_key_exists($key, $this->data) === TRUE){
            return
$this->data[$key];
        }
        else{
            return
"";
        }
    }
}

class
FBDataStore{
    public static function
get($type){
        switch(
$type){
            case
"memcache":
               
$instance = FBDataStore_Memcache::getInstance();
                break;
        }
        return
$instance;
    }
}

class
FBDataStore_Memcache{

    private
$memcache;

    public static function
getInstance(){
        static
$instance;
        if(!isset(
$instance)){
           
$class_name = __CLASS__;
           
$instance = new $class_name();
        }
        return
$instance;
    }

    public function
__construct(){
       
$this->memcache = new Memcache;
       
$app_data = AppData::getInstance();
       
$memcache_servers = $app_data->get("memcache_servers");

        if(
count($memcache_servers) > 0){
            foreach(
$memcache_servers as $name => $server){
               
$this->memcache->addServer($server["host"], $server["port"]);
            }
        }
    }

    public function
set($key, $val, $expire = 0){
        return
$this->memcache->set($key, $val, MEMCACHE_COMPRESSED, $expire);
    }

    public function
get($key){
       
$value = $this->memcache->get($key);
        if(
$value === FALSE){
           
$value = "";
        }
        return
$value;
    }
}

class
FacebookUtil{
    private static
$fb_util;
    private static
$is_application_oauth_authorized;
    private static
$access_token;
    private
$authorization_url;

    public static function
getInstance(){
        static
$instance;
        if(!isset(
$instance)){
           
$class_name = __CLASS__;
           
$instance = new $class_name();
        }
        return
$instance;
    }

    public function
authorizeApplicationWithOAuth($permissions = array()){

       
//make sure this method is called once only
       
if(isset(self::$is_application_oauth_authorized)){
            return
self::$is_application_oauth_authorized;
        }

       
$result = false;

        if(
strlen($this->get('code')) > 0){
           
//this is guaranteed to get the fresh request token
           
$request_token = $this->get('code');
           
$this->setRequestToken($request_token);
           
$this->goToCanvas();
        }
        else{
            if(
$this->get('fb_sig_user') == ""){
               
$this->reAuthorizeApplication($permissions);
            }
        }
        if(
$this->get('fb_sig_user') > 0){
           
//see if the request token is in session
           
$request_token = $this->getRequestToken(); //this is the refresh request token!!!
           
$access_token = $this->getAccessToken();
            if(
strlen($request_token) == 0){
                if(
strlen($access_token) > 0){
         
//check if the old access_token is working or not
                   
if($this->isAccessTokenValid($access_token) === TRUE){
                       
$result = true;
                    }
                }
                else{
                   
//need to re-authorize
                   
$this->reAuthorizeApplication($permissions);
                }
            }
            else{
               
//check if the old access_token is working or not
               
$access_token = $this->getAccessToken();
               
                if(
$this->isAccessTokenValid($access_token) === TRUE){
                   
//the old access token is still working
                   
$result = true;
                }
                else{
                   
//the old access token is not working, get the new one based on the new request token
                   
$access_token = $this->getAccessTokenFromRequestToken($request_token);
                    if(
$this->isAccessTokenValid($access_token) === TRUE){
                       
$this->setAccessToken($access_token);
                       
$result = true;
                    }
                    else{
                       
//need to re-authorize
                       
$this->reAuthorizeApplication($permissions);   
                    }
                }
            }
        }

       
self::$is_application_oauth_authorized = $result;

        return
$result;
    }

    public function
sendCurlRequest($url){
       
$ch = curl_init();
       
curl_setopt($ch, CURLOPT_URL, $url);
       
curl_setopt($ch, CURLOPT_HEADER, 0);
       
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
       
$response = curl_exec($ch);
       
curl_close($ch);
        return
$response;
    }

    public function
sendGraphAPICall($api){
       
$graph_api_base = "https://graph.facebook.com";
       
$access_token = $this->getAccessToken();
       
$response = $this->sendCurlRequest("$graph_api_base/$api?access_token=$access_token");
        return
$response;
    }

    public function
setRequestToken($token){
       
$app_data = AppData::getInstance();
       
$app_id = $app_data->get("application_id");
       
setcookie("{$app_id}_request_token", $token);
    }

    public function
getRequestToken(){
       
$app_data = AppData::getInstance();
       
$app_id = $app_data->get("application_id");
        return
$_COOKIE["{$app_id}_request_token"];
    }

    public function
setAccessToken($token){
       
$user_id = $this->getUserId();
       
$app_data = AppData::getInstance();
       
$app_id = $app_data->get("application_id");
       
$datastore_type = $app_data->get("datastore_type");
       
$data_store = FBDataStore::get($datastore_type); //store the access token into memcache
       
$key = "appdata_{$app_id}_{$user_id}_access_token";
       
$result = $data_store->set($key, $token);
    }

    public function
getAccessToken(){
       
$user_id = $this->getUserId();
       
$app_data = AppData::getInstance();
       
$app_id = $app_data->get("application_id");
       
$datastore_type = $app_data->get("datastore_type");
       
$data_store = FBDataStore::get($datastore_type);
       
$key = "appdata_{$app_id}_{$user_id}_access_token";
        return
$data_store->get($key);
    }

    public function
getAccessTokenFromRequestToken($token){
       
$access_token = "";
       
$app_data = AppData::getInstance();
       
$app_id = $app_data->get("application_id");
       
$connect_url = $app_data->get("connect_url");
       
$app_secret = $app_data->get("application_secret");
       
$response = $this->sendCurlRequest("https://graph.facebook.com/oauth/access_token?client_id=$app_id&redirect_uri=$connect_url&client_secret=$app_secret&code=$token");
        if(
strlen($response) > 0) {
           
$comps = parse_url($response);
           
$path_comps = @explode("=", $comps['path']);
            if(
$path_comps[0] == 'access_token' && strlen($path_comps[1]) > 0){
               
$access_token = $path_comps[1];
            }
        }
        return
$access_token;
    }

    public function
isAccessTokenValid($token){
       
//check if the old access_token is working or not
       
$response = $this->sendCurlRequest("https://graph.facebook.com/me?access_token=$token");
       
$user_data = json_decode($response, true);
        if(
array_key_exists('id', $user_data) === TRUE && $user_data['id'] > 0 && $user_data['id'] == $this->getUserId()){
            return
true;
        }
        else{
            return
false;
        }
    }

    public function
getApplicationMode(){
        if(
$this->get('fb_sig_in_iframe') == 1){
            return
"IFrame";
        }
        else{
            return
"Non IFrame";
        }
    }

    public function
getUserId(){
       
$user_id = 0;
       
$get_user_id = $this->get('fb_sig_user');
        if(
$get_user_id > 0){
           
$user_id = $get_user_id;
        }
        return
$user_id;
    }

    public function
getLocale(){
        return
$this->get('fb_sig_locale');
    }

    private function
get($var_name){ //get a variable value from a get var name
       
if(array_key_exists($var_name, $_GET) === TRUE){
            return
$_GET[$var_name];
        }
        else{
            return
"";
        }
    }

    public function
getAuthorizationURL($permissions){
       
$scope = "";
        if(
count($permissions) > 0){
           
$scope = "&scope=".@implode(",",$permissions);
        }

       
$app_data = AppData::getInstance();
       
$app_id = $app_data->get("application_id");
       
$connect_url = $app_data->get("connect_url");
       
$authorization_url = "https://graph.facebook.com/oauth/authorize?type=client_cred&client_id=$app_id&redirect_uri=$connect_url".$scope;

        return
$authorization_url;
    }

    public function
reAuthorizeApplication($permissions){
       
$authorization_url = $this->getAuthorizationURL($permissions);
       
header("Location: $authorization_url");
    }

    public function
goToCanvas(){
       
$app_data = AppData::getInstance();
       
$canvas_page_url = $app_data->get("canvas_page_url");
       
header("Location: $canvas_page_url");
    }

    public function
isUserLoggedOut(){
        if(
$this->get('fb_sig_logged_out_facebook') == 1){
            return
true;
        }
        else{
            return
false;
        }
    }

    public function
fbQuery($query){
       
$response = $this->sendCurlRequest("https://api.facebook.com/method/fql.query?query=".urlencode($query)."&format=json");
        return
$response;
    }
};

$fb_util = FacebookUtil::getInstance();
if(
$fb_util->isUserLoggedOut() === TRUE){
    exit();
}


$permissions = array(
   
'user_photos',
   
'user_videos',
   
'user_photo_video_tags',
   
'user_status',
   
'offline_access',
   
'publish_stream',
);

if(
$fb_util->authorizeApplicationWithOAuth($permissions) === TRUE){
   
$data['friends'] = json_decode($fb_util->sendGraphAPICall("me/friends"), true);
   
$data['photos'] = json_decode($fb_util->sendGraphAPICall("me/photos"), true);
   
$data['groups'] = json_decode($fb_util->sendGraphAPICall("me/groups"), true);
   
$data['me'] = $fb_util->fbQuery("select pic, name from user where uid = ".$fb_util->getUserId());
}

?>



<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:fb="http://www.facebook.com/2008/fbml">
  <body>
    <div id="content">
<h4>Access Token is <?php echo $fb_util->getAccessToken(); ?></h4>
<h1><?php echo AppData::getInstance()->get('application_id'); ?></h1>
<p>GET DATA: <?php echo print_r($_GET, true); ?></p>
<p>COOKIE DATA: <?php echo print_r($_COOKIE, true); ?></p>
<?php echo print_r($data['me'], true); ?>
<?php //echo print_r($data['friends'], true); ?>
<?php echo print_r($data['photos'], true); ?>
<?php echo print_r($data['groups'], true); ?>
</div>
  </body>
</html>