Call to all developers:

Since this plugin is no longer being developed and is still using the old REST-interface, I’m looking into forking or developing a new Facebook plugin that uses the new OAuth protocol. Please contact me if you’re interested.

We‘re currently working on an extensive symfony (1.4) plugin that builds upon the new Graph API. Watch this blog for further updates!


We have just finished developing our first facebook application using symfony and the very useful sfFacebookConnectPlugin which can be downloaded from the SVN repository (or from here for those of you who don’t use SVN). Simply unpack it to the plugins/ folder of your symfony project.

 

But before you can use the sfFacebookConnectPlugin, you need to install sfGuard:

Installing and configuring sfGuardPlugin and sfFacebookConnectPlugin

Open the command line shell (cmd on Windows, PuTTy/bash on remote systems/linux), change to your project directory and type:

symfony plugin-install http://plugins.symfony-project.com/sfGuardPlugin

to install the plugin from the official symfony repository.

Now open the settings.yml in /apps/[myapp]/config and edit

all:
  .actions:
    login_module:           sfGuardAuth   # To be called when a non-authenticated user
    login_action:           signin     # Tries to access a secure page
    secure_module:          sfGuardAuth   # To be called when a user doesn't have
    secure_action:          secure    # The credentials required for an action
  .settings:
    enabled_modules:      [default, sfFacebookConnectAuth, sfGuardAuth]

Now open myUser.class.php in /[myapp]/lib and update the myUser class to extend sfFacebookUser:

class myUser extends sfFacebookUser
{
}

Add the following lines to the end of your routing.yml at /[myapp]/config to enable the signin and signout (optional):

sf_guard_signin:
 url:   /login
 param: { module: sfGuardAuth, action: signin }

sf_guard_signout:
 url:   /logout
 param: { module: sfGuardAuth, action: signout }

sf_guard_password:
 url:   /request_password
 param: { module: sfGuardAuth, action: password }

Now edit the [myapp]/config/app.yml with all the settings you have obtained from http://www.facebook.com/developers/apps.php:

# default values
all:
 facebook:
   api_key: ...
   api_secret: ...
   api_id: ...
   callback_url: [your callback url]
   app_url: http://apps.facebook.com/[your app]/
   redirect_after_connect: true
   redirect_after_connect_url: 'http://apps.facebook.com/[your app]/'
   connect_signin_url: '[url to your app]/sfFacebookConnectAuth/signin'

 sf_guard_plugin:
   profile_class: sfGuardUserProfile
   profile_field_name: user_id
   profile_facebook_uid_name: facebook_uid
   profile_email_name: email
   profile_email_hash_name: email_hash

 facebook_connect:
   load_routing:     true
   user_permissions: []

Next, you want to modify your sfGuardUserProfile schema (apps/[myapp]/config/schema.yml) to contain these 3 additional rows needed. Simply add them to the end of schema.yml:

sf_guard_user_profile:
 _attributes:      { phpName: sfGuardUserProfile }
 id:
 user_id:     { type: integer, foreignTable: sf_guard_user, foreignReference: id, required: true, onDelete: cascade }
 nickname:         { type: varchar(32), index: unique }
 first_name:       varchar(20)
 last_name:        varchar(20)
 birthday:         date
 facebook_uid:     varchar(20)
 email:            varchar(255)
 email_hash:       varchar(255)

Site note: Since the new Facebook UIDs are way bigger than integer could possibly store, we have decided to go with varchar here. The official README is outdated.


Clear your cache:

symfony cc

Publish your assets:

symfony plugin:publish-assets

And finally, rebuild your model and insert the generated SQL using the database settings you have provided in your /config/databases.yml:

symfony propel:build-model
symfony propel:build-sql
symfony propel:build-forms
symfony propel:build-filters
symfony propel:insert-sql

Using sfFacebookConnectPlugin

We called our module facebook and the layout fb. Of course these are just examples and you may adjust them to your own needs.

Here is our layout fb.php:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" xmlns:fb="http://www.facebook.com/2008/fbml">
<head>
<?php use_helper('sfFacebookConnect') ?>
<?php include_http_metas() ?>
<?php include_metas() ?>
<?php include_title() ?>
<link rel="shortcut icon" href="/favicon.ico" />
</head>
<body>

<?php echo $sf_content ?>

<?php include_bottom_facebook_connect_script(); ?>

</body>
</html>

Next, a very basic actions.class.php:

<?php

/**
 * facebook actions.
 *
 * @package
 * @subpackage facebook
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 12479 2008-10-31 10:54:40Z fabien $
 */
class facebookActions extends sfActions
{
	/**
	 * Executes index action
	 *
	 * @param sfRequest $request A request object
	 */

	public function executeIndex(sfWebRequest $request)
	{
		sfFacebook::requireLogin();
		//get the user object
		$user = $this->getUser();

		// facebook user id
		$this->fb_uid = $user->getCurrentFacebookUid();
		// get or create user based on fb_uid
		$fb_user = sfFacebook::getOrCreateUserByFacebookUid($this->fb_uid);
	}

And finally, and example how to render a friends invite form in your indexSuccess.php:

<?php if ($sf_user->isFacebookConnected()): ?>

<fb:serverfbml style="width: 740px;">
	<script type="text/fbml">
        <fb:fbml>
        	<fb:request-form target="_top" action="[where to redirect after invite]" method="post" type="[name of your app]" content="[text the user will receive]&lt;fb:req-choice url=&quot;http://apps.facebook.com/[your app]/&quot; label=&quot;Accept!&quot;  " image="" invite="true">
        		<fb:multi-friend-selector cols="4" actiontext="[some text above the invite form]" />
	        </fb:request-form>
        </fb:fbml>
    </script>
</fb:serverfbml>

<?php else: ?>
<p>Ooops?</p>
<br />
<?php endif; ?>

I hope you enjoyed this tutorial!

P.S.: Thanks to Andrés for the hint!

P.P.S.: As outlined by Ben below:

The other thing which was an issue I found very hard to spot (I am still new to Symfony) is in the security.yml file in “modules/sfFacebookConnectAuth/config”, if you are using symfony 1.4 (I am not sure about other versions as I haven’t used them), you have to use “false” instead of “off” – if you find that the sfGuardUser record is being created, but the user is not being signed in, this is likely to be the problem. (I believe that this is a change in the syntax of YAML in newer versions).

<?php

/**
* facebook actions.
*
* @package quiz4fun
* @subpackage facebook
* @author Your name here
* @version SVN: $Id: actions.class.php 12479 2008-10-31 10:54:40Z fabien $
*/
class facebookActions extends sfActions
{
/**
* Executes index action
*
* @param sfRequest $request A request object
*/

public function executeIndex(sfWebRequest $request)
{
sfFacebook::requireLogin();
}

public function executeApplet(sfWebRequest $request)
{
sfFacebook::requireLogin();
//get the user object
$user = $this->getUser();

// facebook user id
$this->fb_uid = $user->getCurrentFacebookUid();
// get user based on fb_uid
$fb_user = sfFacebook::getOrCreateUserByFacebookUid($this->fb_uid);

// create a new session ID for authentication
$this->tmp_session = $this->tmpSession();
// write to db
$fb_user->getProfile()->setTmpSession($this->tmp_session);
$fb_user->getProfile()->save();

// nickname
$this->nickname = $fb_user->getProfile()->getNickname();
if(!$this->nickname OR trim($this->nickname) == ”)
{
// set nickname
$this->redirect(‘facebook/updateNickname?nick=fb_’.$this->fb_uid);
}
}

© 2011 burgiblog Suffusion theme by Sayontan Sinha