FaceBook PHP 3.3.1 and Javascript SDK Graph API Tutorial

Recently I was tasked to create a new Facebook application for a client. Since my last application, there were some significant updates to both the Facebook PHP and JavaScript SDK. So I went browsing through the new documentation provided by Facebook, which is currently lacking. I ended up stumbling upon this resource, http://thinkdiff.net/facebook/php-sdk-3-0-graph-api-base-facebook-connect-tutorial/, which was a good basis for the updated SDKs.

The tutorial on thinkdiff was a bit basic and had some issues with the login / logout features. I took a couple of the features from that tutorial and incorporated them into my expanded tutorial.

Changes and New Features:

  • I changed the login feature to use the Javascript login/logout method and updated the code to share the session/cookie with PHP
  • I added a logout.php page in order to clear sessions and delete the FaceBook cookie
  • I added a new feature that will allow users to friend the application profile and comment on the application profile
  • I created a multi-file upload feature that will create an album and upload photos and videos to the user’s profile
  • I also optimized the directory structure and did some code cleanup
Before I begin explaining the various updates of the tutorial, lets start with the updated directory structure:
  • images [folder]
  • includes [folder]
    • css [folder]
      • style.css
    • js [folder]
      • appjs.php – javascript containing Facebook JavaScript SDK methods
      • uploadify.js – javascript file containing uploadify instantiation
    • upload[folder] – containts the uploadify files for photo/video upload
      • … uploadify files
      • uploadify.php – post file for the uploadify AJAX call
    • app.php – php file containing Facebook PHP SDK methods
    • config.php – php file containing configuration options like app id and secret
    • facebook.php – 3.3.1 PHP SDK
    • base_facebook.php - 3.3.1 PHP SDK
  • uploads [folder] – folder where files are uploaded
  • index.php – main file
  • logout.php
Now that you are acquainted with the directory structure, you need to first configure the config.php file located in the includes folder:
//Global Config File
define("APPID", "YOUR_APP_ID"); // application id
define("SECRET", "YOUR_APP_SECRET"); //application secret
define("PROFILEID", "1234567890"); //get the profile ID for the comment on application wall function - easily found by clicking profile photo then rollover the photo and grab fbid from query string
define("PROFILENAME", "John Doe"); //required to see if the user friended your app profile
define("DOMAIN", "epixseo.com"); //if you are using a subdomain don't forget to include it: sub.domain.com

You are going to need each of these options to use all of the features in this tutorial. To find your profile id, click on your Facebook profile photo, then rollover the photo and you’ll see a query string called fbid in the link, that’s what you’re looking for. Once you’ve updated the config file, the application tutorial should run out of the box. Next I’ll explain some of the new functions in detail, starting with the photo / video upload. I decided to use a JQuery plugin called uploadify to streamline this process. Note that in the index.php file I am including the necessary files for that plugin here:

<script type="text/javascript" src="./includes/upload/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="./includes/upload/swfobject.js"></script>
<script type="text/javascript" src="./includes/upload/jquery.uploadify.v2.1.4.min.js"></script>
<script type="text/javascript" src="./includes/js/uploadify.js"></script>

The uploadify.js file is what instantiates the uploadify object and allows you to set configuration options as seen below:

$(document).ready(function() {
$('#file_upload').uploadify({
'uploader' : './includes/upload/uploadify.swf',
'script' : './includes/upload/uploadify.php',
'cancelImg' : './includes/upload/cancel.png',
'folder' : './uploads/<!--?=$user? -->',
'multi' : true,
'onAllComplete' : function(event,data) {
//alert(data.filesUploaded + ' files uploaded successfully!');
window.location = 'index.php?upload=1';
},
'onError' : function (event,ID,fileObj,errorObj) {
alert(errorObj.type + ' Error: ' + errorObj.info);
}
});
});

Note the onAllComplete function. Once all of the selected files in the multi-upload sequence are finished, this event is triggered. Currently, it shoots back to the main index.php file and triggers a PHP sequence which sends the uploaded files to Facebook. This is the general flow:

Select Files To Upload -> Upload -> uploadify.php (includes/upload) processes each upload -> uploads are stored in a folder with the Facebook user id as the folder name in ./upload -> window.location is triggered and index.php grabs the upload query string -> PHP code is initiated to upload the photos/videos to facebook and create an album, as seen below in app.php (includes):

function deleteDirectory($dir) {
$files = glob( $dir . '*', GLOB_MARK );
foreach( $files as $file ){
if( substr( $file, -1 ) == '/' )
delTree( $file );
else
unlink( $file );
}
rmdir( $dir );
}

if (isset($_GET['upload'])){
try{
$dir = "./uploads/$user/";
//define the name of the album
$albumName = 'Application Photos';

if (is_dir($dir)) {
//set upload support
$facebook-&gt;setFileUploadSupport(true);

//Create an album
$album_details = array(
'message'=&gt; 'Your album description goes here',
'name'=&gt; $albumName
);

$param = array(
'method' =&gt; 'fql.query',
'query' =&gt; 'SELECT object_id FROM album WHERE owner="'.$user.'" AND name="'.$albumName. '"'
);
//Check if album exists and get the album id
$album = $facebook-&gt;api($param);
if (!$album) {
$create_album = $facebook-&gt;api('/me/albums', 'post', $album_details);
$album_uid = $create_album['id'];
} else {
$album_uid = $album[0]['object_id'];
}

//open the temp directory
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if (filetype($dir . $file) == 'file') {
//echo "filename: $file : filetype: " . filetype($dir . $file) . "\n";
$theUploadFile = $dir.$file;

//need to find out if this is an image
$imageDetails = getimagesize($theUploadFile);
$checkMime = explode("/", $imageDetails['mime']);

if ($checkMime[0] == 'image') {
//Upload a photo to album of ID...
$photo_details = array(
'message'=&gt; 'Photo Description Goes Here',
'image'=&gt; '@' . realpath($theUploadFile)
);

$upload_photo = $facebook-&gt;api('/'.$album_uid.'/photos', 'post', $photo_details);

} else {

$video_details = array(
'file'=&gt; '@' . realpath($theUploadFile)
);

$upload_video = $facebook-&gt;api('/me/videos', 'post', $video_details);
}
}
}
closedir($dh);
}

//now lets delete the images and temp directory unless you plan on using them with your app
deleteDirectory($dir);
}

Basically what is happening in the above code is I am first going to find the directory I created in /uploads (using user id as folder name) and if it’s found I proceed through the code. The first chunk of code is going to create an album for the photos to be uploaded to (doesn’t apply to videos). First it will check to see if the album exists, if not it will create it and grab the album id. Next I use the php opendir command and iterate through the directory. Facebook uses a slightly different api call for photos and videos so I wrote a function to detect the MIME type. If it’s an image it will use the photo api call otherwise it will use the video call. You can catch any exceptions from the video upload if Facebook doesn’t like the file being uploaded, although they are pretty flexible on the formats they allow.

Once that process is complete, I wrote a deleteDirectory function that will delete the directory we created at the beginning of the upload process. You can remove this function if you want to store the uploads on your server as well, although you could save space by retrieving them from Facebook.

I also added the ability for the user to friend the application wall and post on the application wall. The code for this is in the index.php file and utilizes a Graphi API link like so:

<??php
if ($appFriendId == 0) {
$currentURL = (!empty($_SERVER['HTTPS'])) ? "https://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'] : "http://".$_SERVER['SERVER_NAME'].$_SERVER['REQUEST_URI'];
//note that you must confirm the friend request before the user can use the Comment On Our Wall function
??>
<br /><br />
<a href="http://www.facebook.com/dialog/friends/?id=<?=PROFILEID?>&app_id=<?=APPID?>&redirect_uri=<?=$currentURL?>">Friend the Application Profile</a>
<?? } else { ??>
<br /><br />
<a href="#" onClick="wallPostApp('Your Message Here'); return false;">Comment On Our Wall</a>
<?? } ??>

Basically I am checking against a variable called $appFriendId to see if the user is already a friend. If they are not I present the Friend the Application Profile link, otherwise they get the Comment on Our Wall link (don’t mind double ?? – only way I could show the code). The friend check happens in the app.php file and looks like so:

//get the users friends
$allfriends = $facebook-&gt;api("/$user/friends?fields=id,name");
//function to find friends Id by name - used for commenting on application wall and detecting if we should show add friend link
function findFriendIdByName($data, $name) {
$friendedApplication = 0;
foreach ($data as $value) {
if (strtolower($value['name']) == strtolower($name)) {
return $value['id'];
break;
}
}
return 0;
}

$appFriendId = findFriendIdByName($allfriends['data'], PROFILENAME);

The function is used to find the friend by name (EpixSEO or John Doe, etc). It could be changed to find friend by id, username, etc. Since you’re really just trying to find yourself its up to you what you decide to use.

I also created a custom logout.php file. I noticed that just following the Javascript logout function doesn’t get rid of session / cookie data for PHP, check out the code below:

require 'includes/config.php';

// Initialize the session.
// If you are using session_name("something"), don't forget it now!
session_start();

// Unset all of the session variables.
$_SESSION = array();

// If it's desired to kill the session, also delete the session cookie.
// Note: This will destroy the session, and not just the session data!
if (ini_get("session.use_cookies")) {
    $params = session_get_cookie_params();
    setcookie(session_name(), '', time() - 42000,
        $params["path"], $params["domain"],
        $params["secure"], $params["httponly"]
    );
}

// Finally, destroy the session.
session_destroy();

// Now lets remove the cookie
setcookie ('fbsr_'.APPID, ' ', time() - 3600);
setcookie ('fbsr_'.APPID, ' ', time() - 3600, "/", '.'.DOMAIN); //the . before the domain will take care of subdomains

header('Location: index.php');

In the logout.php file I first reset the $_SESSION array, then I find the session cookie and use setcookie to reset the cookie and expire it by setting the time back. After that I destroy any sessions using session_destroy. The last step is to find the Facebook cookie, which is always named fbsr_YOUR-APP-ID. After that cookie is reset I redirect back to index.php and the user is presented with the login button.

Well that’s the updated tutorial in a nutshell. Don’t forget to check out the original one located at thinkdiff.net where they talk about some of the functions I didn’t cover (remember I also stripped out some of their code).

PLEASE COMMENT and let me know if you find any bugs or have suggestions / general comments. Thanks and enjoy!

9 Comments

  1. Gr8 new tut on FB :)

    also, cud u tell me which plugin u used for SOURCE CODE WRAPPING ?

    • I am not using any plugins for source code wrapping.

  2. Thanks for the tutorial.

    I’m having a problem getting the photo upload to work. When I select files and hit upload I see the progress bars complete and the page refreshes, but when I check my facebook page I do not see any photos appear in my albums. Everything else works (posting status etc).

    • The photos are uploaded to the Uploads folder in the directory, you probably need to set read/write permissions on the directory.

      • Hi,

        having same problem which Keith has got… pics uploaded to the uploads/ folder on our server but it there is no pic in our facebook account :(

  3. Hi,

    I tried the script, but cant seem to get beyond the login page.

    What could be wrong?

  4. Can anybody help me? I filled in the details for the config.php, but nothing else seems to be working on the script. The login button doesnt respond and from there nothing really happens. I really wish i could use the code examples here to do project am working on

    Thanks for your help1 am a noob here!

  5. I tried to test the application and it doesnt work. The login button just stays there even when clicked. Is there any reason why it is doing that? Can anyone help? I will really love it if someone here could give me a reason for the error.

    Thanks

  6. Hi,

    When I click on “login”, nothin happens.

    I have just changed
    - App ID
    - App Secret

    Do you have a solution ?




 
RT @ZVirtualCorp: Benefits Of Buying Used Binding Equipment | http://t.co/R2TZoWPK
Wordpress Themes - Wordpress Video Themes - Wordpress Travel Themes - WordPress Restaurant Themes