![]()
While the title might sound a tad complicated, the problem is pretty straight forward:
Your production environment consists of a multi-server set-up (e.g. a cluster, but works on a single server just as well) with a centralised database and you use sfFileCache as your caching strategy (because you don’t want to litter your database with cache entries).
So how would you clear parts or all of the cache? You can’t just use symfony:cc or the sfViewCacheManager because:
- It won’t work across applications, e.g. when triggered from your backend application, you won’t be able to clear the cache on your frontend.
- It will only clear the cache on your current server, while the other servers still contain the old cache version.
Every programmer knows it, every programmer loves it: the Eclipse IDE. It is probably the most extensive free open-source development environment out there (Netbeans put aside). In this tutorial I’d like to show you how you can get it ready for symfony, the (in my opinion) best PHP framework there is at the moment.
1. Download and install the Eclipse-based PDT (PHP Development Tools) standalone version: http://www.eclipse.org/pdt/
2. Now we’re going to install some plugins that are going to make your life easier when you are a symfony developer. Click Help -> Install New Software … and add the following plugins to Eclipse:
- Aptana Studio Update Site – http://update.aptana.com/update/studio/ -> Aptana Studio (only if you want to use the built-in FTP functionality, otherwise you don’t need to bother about this one)
- YEdit – http://dadacoalition.org/yedit -> YEdit (a YAML syntax highlighter, since most of symfony’s configuration is being done through .yml files
3. After restarting Eclipse, we are going to add some symfony-specific auto-completion features to Eclipse. At this point, you will probably have the symfony framework installed somewhere on your PC. If you have not done so, download it from here or here and unpack it to a directory that you can easily remember.
Now change back to Eclipse. Open Window -> Preferences -> PHP -> PHP Libraries -> New, enter “symfony” as a name and tick the Add to environment option. After clicking OK, you will notice the entry we just added in your libraries list. Mark the new entry by clicking on it, the click Add external folder…, browse to the folder where you put the symfony framework and add it.
Now you can add the symfony library every time you create a new PHP Project in Eclipse or by right-clicking on an existing project ->Include Path -> Configure include path. Either way, you need to click on Add Library -> User Library -> symfony and add it.
4. If you have installed the Aptana plugin before, you might want to activate the built-in shortcut for uploading the current file you are working on. Since that shortcut (Ctrl + Shift + U) is already reserved by Eclipse itself (and the Aptana team probably did not think of that when writing their framework), you need to do the following steps: Window -> Preferences -> General -> Keys, then do a search for “Show Occurrences in File Quick Menu” (filter) and unbind these shortcuts from this rather useless command (Click -> Unbind Command).
You need to modify the Sync Manager (that is needed for uploading). Click Window -> Show View -> Other -> Aptana Standard Views -> Sync Manager. The configuration window will pop up at the bottom of Eclipse. Configuration is pretty much self-explanatory. Just make sure you have the FTP data for you symfony-enabled web server at hand.
Now you can start developing beautiful symfony applications with Eclipse! There are dozens of (video) tutorials about how to effectively use Eclipse out there, so you might want to have a look at these if you’ve never used Eclipse before (I absolutely recommend that, it will save you loads of time). To start a new project, select File -> New -> PHP Project, enter the necessary data and don’t forget to include the symfony library.
If you’re running you own server on localhost (a future tutorial will cover how to set one up with symfony enabled), another feature will come in quite handy as well: right-clicking on the project in your PHP Explorer and selecting Command Line Shell will start a shell with the project’s root folder. From there, you can start to use your symfony commands as usual.
Have fun developing symfony applications even quicker and easier!
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]<fb:req-choice url="http://apps.facebook.com/[your app]/" label="Accept!" " 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);
}
}
