Building A Facebook Application With AMFPHP

Follow Me on Pinterest

Building A Facebook Application With AMFPHP

I have recently completed a new project for HBO which is a True Blood Facebook application with a Flash component and uses an AMFPHP gateway to make calls to the Facebook Graph API and returns user information, friends, posts to wall etc.

I approached the project by making sure that all Facebook functionality is abstracted from Flash and run purely through the gateway and can also be called from other php scripts.

In order to achieve this I Built a singleton class that sets up the Facebook application and allows calls to be made from from gateway.

Below shows the class that we use in conjunction with the Facebook PHP SDK to handle facebook calls.

UPDATE: Initially I used some functionality to determine and prompt for a users permissions but this has since become unsupported in the Facebook API, because of this me and a colleague implemented a Javascript solution to redraw the flash swf based on the user accepting the required permissions. This code can be found on my colleague Robert Turall‘s blog post but I will add a version for you to look at on my blog soon.

FacebookApi.class.php

/**
 * FacebookApi
 *
 * Class to authenticate a facebook application
 *
 * @author				Neil Young neil.young@substance001.com
 * @copyright			Copyright (c) 2010, Neil Young
 * @version				0.9
 *
 * Before getting the instance for this class you will need to set all
 * the facebook application variables e.g.
 *
 *	//get the facebook api object so we can make facebook calls
 *	$FacebookApi = FacebookApi::GetInstance();
 *
 *	// set configuration variables
 *	$FacebookApi->SetApplicationId(APPLICATION_ID);
 *	$FacebookApi->SetApplicationSecret(APPLICATION_SECRET);
 *	$FacebookApi->SetCanvasUrl(CANVAS_URL);
 *	$FacebookApi->SetDomainUrl(DOMAIN_URL);
 *
 * Once you have done this you can call $FacebookApi->Setup(); from a script or amfphp construct
 *
 * if running through AMFPHP you will need to tell the FacebookApi class like so:
 *
 * 	//get the facebook api object so we can make facebook calls
 *	$this->oFacebookApi = FacebookApi::GetInstance();
 *
 *	//setup the facebook api object
 *	$this->oFacebookApi->Setup();
 *
*/
class FacebookApi
{
	/**
	 * PROPERTIES
	 */

	/**
	 * @var static object $oFacebookApi
	 */
	private static $oFacebookApi = '';

	/**
	 * @var object $Facebook
	 */
	protected $Facebook = NULL;

	/**
	 * @var string $applicationId
	 */
	public $applicationId = "";

	/**
	 * @var string $applicationSecret
	 */
	public $applicationSecret = "";

	/**
	 * @var string $canvasUrl
	 */
	public $canvasUrl = "";

	/**
	 * @var string $domainUrl
	 */
	public $domainUrl = "";

	/**
	 * @var string $accessToken
	 */
	public $accessToken = NULL;

	/**
	 * FacebookApi - GetInstance()
	 *
	 * get an instance of the FacebookApi class
	 *
	 * @author					Neil Young neil.young@neilyoungcv.com
	 * @copyright				Copyright (c) 2010, Neil Young
	 * @param object			$Db
 	 *
	 */
	public static function GetInstance()
	{
		if (!self::$oFacebookApi)
		{
			self::$oFacebookApi = new FacebookApi();
		}

		return self::$oFacebookApi;
	} 

	/**
	 * FacebookApi - Setup
	 *
	 * setup the facebook application
	 *
	 * @author				Neil Young neil.young@substance001.com
	 * @copyright			Copyright (c) 2010, Neil Young
	 * @version				0.9
	 *
	*/
	public function Setup()
	{
		//check if all application details have been provided
		//you will need to setup this application on facebook
		if ($this->GetApplicationId() != "" && $this->GetApplicationSecret() != "" && $this->GetDomainUrl() != "" && $this->GetCanvasUrl() != "")
		{
			// Create our Application instance.
			$this->Facebook = new Facebook(array(
			 'appId'  => $this->GetApplicationId(),
			 'secret' => $this->GetApplicationSecret(),
			 'cookie' => true,
			 'domain' => $this->GetDomainUrl()
			));

			//get the session
			$session = $this->Facebook->getSession();

			try
			{
				//setup a token attachment
				$token =  array('access_token' => $session["access_token"]);

				//make a request to the graph api
				$this->Facebook->api('/me');

				//set the sessions access token
				$this->accessToken = $session["access_token"];
			}
			catch(Exception $e)
			{
				die("There was a problem with the Facebook session");
			}
		}
		else
		{
			//user has not supplied the facebook details
			return false;
		}
	}

	/**
	 * FacebookApi - HasSession()
	 *
	 * Determines if a user has a session
	 *
	 * @author				Neil Young neil.young@substance001.com
	 * @copyright			Copyright (c) 2010, Neil Young
	 * @version				0.9
	 *
	*/
	public function HasSession()
	{
		//get the active session
		$session = $this->Facebook->getSession();

		//return if the session exists
		return (!$session) ? false : true;
	}

	/**
	 * FacebookApi - GetSession()
	 *
	 * Gets the active session
	 *
	 * @author				Neil Young neil.young@substance001.com
	 * @copyright			Copyright (c) 2010, Neil Young
	 * @version				0.9
	 *
	*/
	public function GetSession()
	{
		//get the active session
		$session = $this->Facebook->getSession();

		//return it!
		return $session;
	}

	/**
	 * FacebookApi - MakeApiRequest()
	 *
	 * Makes a request to the Facebook API
	 *
	 * @author				Neil Young neil.young@substance001.com
	 * @copyright			Copyright (c) 2010, Neil Young
	 * @version				0.9
	 *
	 * @param	string		$request (e.g. /me/friends)
	 * @param	method		$method (e.g. get, post, delete)
	 * @param 	array		$vars (access token is automatically appended)
	 *
	*/
	public function MakeApiRequest($request, $method = 'get', $vars = array(), $accessToken = "")
	{
		//attempt to access the facebook api
		try
		{
			//determine access token to use
			//we determine if the function has an access token passed or if we are using the
			//logged in users access token - passing in can be useful for test users
			$accessToken = ($accessToken == "") ? $this->accessToken : $accessToken;

			//build vars array
			$vars = array_merge($vars, array("access_token" => $accessToken));

			//make a request to the graph api
			$response = $this->Facebook->api($request, $method, $vars);

			//return the response
			return $response;
		}
		catch(Exception $e)
		{
			//an error was encountered, return it
			return "Facebook Error Response: " . $e->getMessage();
		}
	}

	/**
	 * FacebookApi - __call()
	 *
	 * Detect get and set method calls to class and dynamically create these functions
	 *
	 * @author				Neil Young neil.young@substance001.com
	 * @copyright			Copyright (c) 2011, Neil Young
	 * @version				0.9
	 *
	 * @param string		$method
	 * @param array			$arguments
	*/

	public function __call($method, $arguments)
	{
		$prefix = strtolower(substr($method, 0, 3));

		$property = strtolower(substr($method, 3));

		if (empty($prefix) || empty($property))
		{
			return;
		}

		if ($prefix == "get" && isset($this->$property))
		{
			return $this->$property;
		}

		if ($prefix == "set")
		{
			$this->$property = $argument;
		}
	}
}

config.inc.php

In our configuration we just setup constants to hold our Facebook application details and set them for the FacebookApi class.

//fix for how safari and ie handle sessions
header('P3P: CP="CAO PSA OUR"');

//start the session
session_start();

// relative path
define("RELATIVE_PATH", $_SERVER["DOCUMENT_ROOT"] . "/");

// absolute path
define("ABSOLUTE_PATH", "http://" . $_SERVER["HTTP_HOST"] . "/");

//include facebook class
require_once(RELATIVE_PATH . "/lib/external/facebook.php");

//store facebook configurations in constants, we may want to use them in other
//class pages
define("APPLICATION_ID", "YOUR APPLICATION ID");
define("APPLICATION_SECRET", "YOUR APPLICATION SECRET");
define("CANVAS_URL", "YOUR CANVAS URL");
define("DOMAIN_URL", "YOUR DOMAIN URL");

// get FacebookApi singleton class
$FacebookApi = FacebookApi::GetInstance();

// set configuration variables
$FacebookApi->SetApplicationId(APPLICATION_ID);
$FacebookApi->SetApplicationSecret(APPLICATION_SECRET);
$FacebookApi->SetCanvasUrl(CANVAS_URL);
$FacebookApi->SetDomainUrl(DOMAIN_URL);

ApplicationGateway.php

Below shows how we use the FacebookApi class inside the gateway.

/**
 * ApplicationGateway
 *
 * Gateway class
 *
 * @author				Neil Young neil.young@substance001.com
 * @copyright				Copyright (c) 2011, Neil Young
 * @version				0.9
 *
*/

//include configuration (in the root - out of services and amfphp and into "inc" folder)
include_once('../../inc/config.inc.php');

class ApplicationGateway
{
	/**
	 * PROPERTIES
	 */

	/**
	 * @var object $oFacebookApi
	 */
	 protected $oFacebookApi = NULL;

	/**
	 * ApplicationGateway - __contruct
	 *
	 * construct
	 *
	 * @author				Neil Young neil.young@substance001.com
	 * @copyright				Copyright (c) 2011, Neil Young
	 * @version				0.9
	 *
	*/
	public function __construct()
	{
		//get the facebook api object so we can make facebook calls
		$this->oFacebookApi = FacebookApi::GetInstance();

		//setup the facebook api object
		$this->oFacebookApi->Setup();
	}

	/**
	 * ApplicationGateway - GetLoggedInUser()
	 *
	 * Get the logged in user
	 *
	 * @author				Neil Young neil.young@substance001.com
	 * @copyright				Copyright (c) 2011, Neil Young
	 * @version				0.9
	 *
	 *
	*/
	public function GetLoggedInUser()
	{
		//attempt to execute code
		try
		{
			//get the logged in user
			$data = $this->oFacebookApi->MakeApiRequest('/me');

			//check to see an array has been returned
			if (!is_array($data))
			{
				//throw exception with the Facebook response
				throw new Exception($data);
			}
			else
			{
				//build user array
				$user["userId"] = $data["id"];
				$user["name"] = $data["name"];
				$user["picture"] = "http://graph.facebook.com/" . $data["id"] . "/picture?type=square";

				//return response
				return $data;
			}

		}
		catch(Exception $e)
		{
			//return response
			return $e->getMessage();
		}
	}
}

You can check this by going to your application in Facebook and then firing up your AMFPHP browser.

You should now be able to call GetLoggedInUser() and should return the logged in users (your!) details.

If you are using offline access for your applications you could extend the application further by having a database table that stores the session details e.g. access token and uid and then select the user by their uid and pass the access token into the MakeApiRequest() function!

Thats it, nice and easy!

If you have any questions please feel free to leave comments below.

Filed Under: Code Share, Latest Projects
Tags: , , , , , , , , .
Bookmark: permalink.

Let me know what you think:

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>