Академический Документы
Профессиональный Документы
Культура Документы
Overview
This tutorial is designed to help Facebook and Zend Framework developers access the Facebook Graph API from within their IFrame application on the Facebook Platform. This may not be the BEST method of accessing the Graph API but it is intended as a decent starting point for your own implementation. It presumes you have completed part 1 in the series, which describes the authentication process.
Then in the created model, let's just make an empty class extending Zend_Exception:
<?php class Application_Model_FacebookException extends Zend_Exception { }
We now have a custom exception we can throw wherever we want by utilising ZF's autoloading of models. So lets change the exception in the indexController to use this new exception:
public function indexAction() { // Grab the signed request and setup the Facebook model $signed_request = $this->_getParam('signed_request', null); if(empty($signed_request)) { throw new Application_Model_FacebookException('Security Error'); } ...
NOTE: There is a valid school of thought that says exception classes should not sit in the Model name space. This is probably true, but for the sake of simplicity in this tutorial, it's OK. Job done.
// Add the access token we were passed in the encoded sigs to the request $args['access_token']=$this->fbData['oauth_token']; // Set the get parameters to the arguments we need $http->setParameterGet($args); try { // do the request $request = $http->request(); // if the status isn't 200 (OK) if($request->getStatus() != 200) { throw new Application_Model_FacebookException('Error requesting data.. Status: '.$request->getStatus()); } else { // Return the decoded object as an array return Zend_Json::decode($request->getBody(), Zend_Json::TYPE_ARRAY); } } catch (Exception $e) { throw new Application_Model_FacebookException('Error from Facebook API: '. $e->getMessage()); } }
The crucial part here is that the authentication token we need to access the graph as the logged in user has already been passed to us as part of the encoded signed_request parameter posted to our IFrame. So to get the data we want from the Graph we only need to pass the GET parameter access_token with this value. This is the beauty of using the IFrame authentication mechanism, it allows us to access the Graph without us having to mess around with the bothersome OAuth 2.0 authentication methods; the access token is handed to us on a plate! So, lets create a container function that returns details about the currently logged in user, again, we are working in the Facebook Model:
/** * Returns information about the currently logged in user * @return array */ public function getUserInfo() { $url = self::FACEBOOK_GRAPH_URL.'me'; return $this->_getFromGraph($url); }
All this function does is to compose the url, which would be http://graph.facebook.com/me, and passes it to our getFromGraph private function. Outputting this function, you will see you get returned an array of information straight from the Facebook Graph API:
array(8) { ["id"] => string(9) "Redacted" ["name"] => string(11) "Gary Hockin" ["first_name"] => string(4) "Gary" ["last_name"] => string(6) "Hockin" ["link"] => string(48) "http://www.facebook.com/profile.php?id=Redacted" ["locale"] => string(5) "en_GB"
It's really as simple as that, the data is in a handy array format for you to do with as you will in your application.
Going Further
Lets look at adding another request from the Graph API, lets take a look at the entry points available at http://developers.facebook.com/docs/reference/api/
NOTE: Not all of these entry points will be available to you from the basic permissions we allowed in the first tutorial, if you want access to more data, you will have to request more permissions, we will cover this in a later tutorial. A common function you will need in any Facebook application is to retrieve a list of a users Facebook friends, we can see from the above that the entry point is https://graph.facebook.com/me/friends, because of the way we have coded the wrapper function, adding this function to the Facebook model is simple:
/** * Returns a list of a user's Facebook friends * @return array */ public function getUserFriends() { $url = self::FACEBOOK_GRAPH_URL.'me/friends'; return $this->_getFromGraph($url); }
As you can see, it is nice and easy to compose the correct url, and pass it to the wrapper function. Running this will return a nice array in the format of:
array(1) { ["data"] => array(185) { [0] => array(2) { ["name"] => string(10) "Emma Jones" ["id"] => string(9) "123456789" } [1] => array(2) { ["name"] => string(14) "Mary Barnett" ["id"] => string(9) "1234567890"
As you can see, the FQL entry point is not the same as the Graph entry point, next lets create a wrapper function that allows us to run FQL queries.
/** * Gets data from the Facebook FQL API * @param string $fql */ protected function _doFQLQuery($fql) { // Check if the user is authed if (!$this->isAuthed) { throw new Application_Model_FacebookException('User is not authenticated'); } $url = self::FACEBOOK_FQL_URL; $args = array( 'query' => $fql, 'format' => 'json' ); return $this->_getFromGraph($url, $args); }
Lets grab a list of the user's friends who are have also installed our application. This would be a very useful query in a real-world application, as it allows us to generate leaderboards, and also grab a list of potential users to send gifts to. The FQL to do this is:
SELECT uid FROM user WHERE has_added_app=1 and uid IN (SELECT uid2 FROM friend WHERE uid1 = <fbid>)
So, let's modify our getUserFriends function to return either a list of all a users' friends, or just the friends who are using the application.
/** * Returns a list of a user's Facebook friends * @param bool $justUsingApp Only return friends who are using this app? * @return array */ public function getUserFriends($justUsingApp = false)
{ if(!$justUsingApp) { $url = self::FACEBOOK_GRAPH_URL.'me/friends'; return $this->_getFromGraph($url); } else { $fql = "SELECT uid FROM user WHERE has_added_app=1 and uid IN (SELECT uid2 FROM friend WHERE uid1 = {$this->fbData['user_id']})"; return $this->_doFQLQuery($fql); } }
And there we have it, using FQL we can grab far more specific information than just using the Graph API, and even information that isn't available through the Graph. It is also arguably considered a faster method of grabbing data, but the community is divided on this, personally I think that since the Graph API became available then the two methods are comparable.
Next Time
In the next tutorial, we will be looking at using Javascript to interact with Facebook, to post stories to users' walls, and other clever things. We will also look at how the tutorial code could and should be modified for use in a production environment.
Further Reading
Facebook documentation on the Graph API: http://developers.facebook.com/docs/reference/api/ Facebook documentation on FQL queries: http://developers.facebook.com/docs/reference/fql/