Wednesday, January 12, 2011

Writing Facebook applications using the new API

If you are FB app programmer, you must have definitely got to know  that their API  changed pretty recently. In this article I’m focusing facebook latest php sdk to integrate facebook features in your site. Some days ago facebook released their new graph api system and updated their core structure. They also officially released php sdk so that you can easily call facebook latest graph api and old legacy api from server side by php.

In this post I’ll show
  1. How to check valid session of user, if user successfully logged in
  2. How to call graph api
  3. How to call legacy api
  4. How to update status dynamically using graph api
  5. How to use FQL Query
Note: If you are new to FB application programming, it is stronlgy recommended that you first read http://developers.facebook.com/docs/api to understand basics of FB app proggraming.

STEP 1:
First download the php sdk libary from here . Now copy the facebook.php from /src/ to your project dir.

STEP 2:
Create a file named fbmain.php. And copy below code to this file.

<?php
    $fbconfig['appid' ]  = "your application id";
    $fbconfig['api'   ]  = "your application api key";
    $fbconfig['secret']  = "your application secret key";
    try{
        include_once "facebook.php";
    }
    catch(Exception $o){
        echo '<pre>';
        print_r($o);
        echo '</pre>';
    }
    // Create our Application instance.
    $facebook = new Facebook(array(
      'appId'  => $fbconfig['appid'],
      'secret' => $fbconfig['secret'],
      'cookie' => true,
    ));
    // We may or may not have this data based on a $_GET or $_COOKIE based session.
    // If we get a session here, it means we found a correctly signed session using
    // the Application Secret only Facebook and the Application know. We dont know
    // if it is still valid until we make an API call using the session. A session
    // can become invalid if it has already expired (should not be getting the
    // session back in this case) or if the user logged out of Facebook.
    $session = $facebook->getSession();
    $fbme = null;
    // Session based graph API call.
    if ($session) {
      try {
        $uid = $facebook->getUser();
        $fbme = $facebook->api('/me');
      } catch (FacebookApiException $e) {
          d($e);
      }
    }
    function d($d){
        echo '<pre>';
        print_r($d);
        echo '</pre>';
    }
?>


First update $fbconfig array by your application’s id, api key and secret key. In the code you’ll see I included facebook.php by include_once. If your server has no curl extension and json extension, you’ll see error message. Until you don’t install curl and json extension this sdk will not work.

$session = $facebook->getSession();
This method returns session information of user. It may be empty if user yet not logged in your site or user’s session is invalid. To check user’s session validity you’ve to first call an api, if user’s session is valid then the api will return result.

So if $fbme is not null that means user successfully logged in via facebook and user’s session is valid. So before calling any api use conditional logic like if ($fbme) { then call api}.

I also defined a method named d() to dump data quickly.

STEP 3:
Now create another file named index.php and copy below code and checkout my description at the end.


   
  
  
<?php
    include_once "fbmain.php";
    $config['baseurl']  =   "place your base url here. Example: http://test.it/test/index.php";
    //if user is logged in and session is valid.
    if ($fbme){
        //Retriving movies those are user like using graph api
        try{
            $movies = $facebook->api('/me/movies');
        }
        catch(Exception $o){
            d($o);
        }
        //Calling users.getinfo legacy api call example
        try{
            $param  =   array(
                'method'  => 'users.getinfo',
                'uids'    => $fbme['id'],
                'fields'  => 'name,current_location,profile_url',
                'callback'=> ''
            );
            $userInfo   =   $facebook->api($param);
        }
        catch(Exception $o){
            d($o);
        }
        //update user's status using graph api
        if (isset($_POST['tt'])){
            try {
                $statusUpdate = $facebook->api('/me/feed', 'post', array('message'=> $_POST['tt'], 'cb' => ''));
            } catch (FacebookApiException $e) {
                d($e);
            }
        }
        //fql query example using legacy method call and passing parameter
        try{
            //get user id
            $uid    = $facebook->getUser();
            //or you can use $uid = $fbme['id'];
            $fql    =   "select name, hometown_location, sex, pic_square from user where uid=" . $uid;
            $param  =   array(
                'method'    => 'fql.query',
                'query'     => $fql,
                'callback'  => ''
            );
            $fqlResult   =   $facebook->api($param);
        }
        catch(Exception $o){
            d($o);
        }
    }
?>
<!DOCTYPE html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
        <title>Facebook app tutorial</title>
    </head>
<body>
    <div id="fb-root"></div>
        <script type="text/javascript">
            window.fbAsyncInit = function() {
                FB.init({appId: '<?=$fbconfig['appid' ]?>', status: true, cookie: true, xfbml: true});
                /* All the events registered */
                FB.Event.subscribe('auth.login', function(response) {
                    // do something with response
                    login();
                });
                FB.Event.subscribe('auth.logout', function(response) {
                    // do something with response
                    logout();
                });
            };
            (function() {
                var e = document.createElement('script');
                e.type = 'text/javascript';
                e.src = document.location.protocol +
                    '//connect.facebook.net/en_US/all.js';
                e.async = true;
                document.getElementById('fb-root').appendChild(e);
            }());
            function login(){
                document.location.href = "<?=$config['baseurl']?>";
            }
            function logout(){
                document.location.href = "<?=$config['baseurl']?>";
            }
</script>
<style type="text/css">
    .box{
        margin: 5px;
        border: 1px solid #60729b;
        padding: 5px;
        width: 500px;
        height: 200px;
        overflow:auto;
        background-color: #e6ebf8;
    }
</style>
    <h3>Facebook app tutorial</h3>
    <?php if (!$fbme) { ?>
        You've to login using FB Login Button to see api calling result.
    <?php } ?>
    <p>
        <fb:login-button autologoutlink="true" perms="email,user_birthday,status_update,publish_stream"></fb:login-button>
    </p>
    <!-- all time check if user session is valid or not -->
    <?php if ($fbme){ ?>
    <table border="0" cellspacing="3" cellpadding="3">
        <tr>
            <td>
                <!-- Data retrived from user profile are shown here -->
                <div class="box">
                    <b>User Information using Graph API</b>
                    <?php d($fbme); ?>
                </div>
            </td>
            <td>
                <div class="box">
                    <b>User likes these movies | using graph api</b>
                     <?php d($movies); ?>
                </div>
            </td>
        </tr>
        <tr>
            <td>
                <div class="box">
                    <b>User Information by Calling Legacy API method "users.getinfo"</b>
                    <?php d($userInfo); ?>
                </div>
            </td>
            <td>
                <div class="box">
                    <b>FQL Query Example by calling Legacy API method "fql.query"</b>
                    <?php d($fqlResult); ?>
                </div>
            </td>
        </tr>
    </table>
    <div class="box">
        <form name="" action="<?=$config['baseurl']?>" method="post">
            <label for="tt">Status update using Graph API</label>
            <br />
            <textarea id="tt" name="tt" cols="50" rows="5">Write your status here and click 'submit'</textarea>
            <br />
            <input type="submit" value="Update My Status" />
        </form>
        <?php if (isset($statusUpdate)) { ?>
            <br />
            <b style="color: red">Status Updated Successfully! Status id is <?=$statusUpdate['id']?></b>
         <?php } ?>
    </div>
    <?php } ?>
    </body>
</html>

The code is very easy to understand. First part contains php logic, api call and collection of data. Next part is html/javascript to view data (javascript for fbconnect authentication).

Please change,

$config['baseurl']  =   "place your base url here. Example: http://test.it/test/index.php";
 
 
And set baseurl to your project url. And never forget to set your facebook application Connect URL. It would be your project url.

In index.php I used javascript based fbconnect authentication and fbml tag  to show login button and logout button. If you don’t want to use javascript for this purpose, you can generate login/logout links using php code.
Generate login/logout button using this php code

// login or logout url will be needed depending on current user state.
if ($fbme) {
  $logoutUrl = $facebook->getLogoutUrl();
} else {
  $loginUrl = $facebook->getLoginUrl();
}

And show the generated links by below code.

<?php if ($fbme) { ?>
    <a href="<?=$logoutUrl?>">
    </a>
    <?php else: ?>
    <a href="<?=$loginUrl?>">
    </a>
    <?php } ?>

So user will see php generated login and logout button.

In the facebook.php sdk the getLoginUrl() function is defined as

/ * The parameters:
   * - next: the url to go to after a successful login
   * - cancel_url: the url to go to after the user cancels
   * - req_perms: comma separated list of requested extended perms
   * - display: can be "page" (default, full page) or "popup"
   *
   * @param Array $params provide custom parameters */
public function getLoginUrl($params=array()){....}

 So if you want that your user approve additional permissions at the first time then generate the url by providing some parameters,


$loginUrl = $facebook->getLoginUrl(
     array('req_perms' => 'email,read_stream')
);

Now lets discuss more about api calling…

1. How to check valid session of user, if user successfully logged in

I already discussed it in the STEP 1. So I think you already have learned how to check valid session of user. Just remember to use if ($fbme) {call api}

2. How to call graph api 

Its very simple. For http://graph.facebook.com/me  you’ve to use

$fbme = $facebook->api('/me');

3. How to call legacy api
 
This is almost same as of graph api calling.

$param  =   array(
   'method'  => 'users.getinfo',
   'uids'       => $fbme['id'],
   'fields'     => 'name,current_location,profile_url',
   'callback'  => ''
);
$userInfo   =   $facebook->api($param);

So $facebook->api() is used to call both graph api and old legacy api. If you check the api() method in facebook.php sdk you’ll see,


public function api() {
   $args = func_get_args();
   if (is_array($args[0])) {
     return $this->_restserver($args[0]);
   } else {
     return call_user_func_array(array($this, '_graph'), $args);
   }
 }

That means if 1st argument is array then the api will call the old restserver.php  otherwise it will call the new graph server.

4. How to update status dynamically using graph api

try {
      $statusUpdate = $facebook->api('/me/feed', 'post', array('message'=> 'sample status message', 'cb' => ''));
} catch (FacebookApiException $e) {
      d($e);
}

in facebook.php you’ll see,

function _graph($path, $method='GET', $params=array()) {...}

So the first parameter is for graph path in here https://graph.facebook.com/me/feed, 2nd parameter defines HTTP post or get parameter and 3rd parameter defines array that contains necessary values. So ‘message’ is the message we want as status and ‘cb’ is the callback function which I set to null. Here http://developers.facebook.com/docs/api you’ll see all the information about graph api and their parameters, like,

Method Description Arguments
/PROFILE_ID/feed write to the given profile’s feed/wall messagepicturelinkname,description

So to call any graph api just check the manual if you need to pass additional parameters or not.

Another example to retrieve user favorite movie names (https://graph.facebook.com/me/movies) use,
$movies = $facebook->api('/me/movies');

5. How to use FQL Query

Currently I don’t find any way to call fql query using graph api. So use the technique of legacy api calling to run fql query,

$fql    =   "select name, hometown_location, sex, pic_square from user where uid=xxxxxxxxxxxxxxx";
$param  =   array(
       'method'     => 'fql.query',
        'query'     => $fql,
      'callback'    => ''
);
$fqlResult   =   $facebook->api($param);

Hope this helps......!

No comments:

Post a Comment