Categories
symfony

Extra questions and solutions for sfGuardPlugin

Hi,

I really know a very little number of symfony projects where would not be used sfGuardPlugin. I should say I’ve seen a few custom self-written user authentification solutions but I did not notice much difference. So in other words those were wheel re-inventions.

Here is a good place to find the answers on the most of related to this plugin questions:

http://trac.symfony-project.com/wiki/sfGuardPluginExtraDocumentation

But you may be looking also for the following solutions which are not hightlighted there:

1. How to extend sfGuardPlugin?
2. How to practically use multi-roles (groups) in sfGuardPlugin?
3. How to implement complicated user statuses (e.g. active, pending, frozen)?

I’m sure there must be more questions and please feel free to ask them 🙂

How to extend sfGuardPlugin

Pure sfGuard provides only basic functionality for authentificating, logging, etc. If you need “signup”, “forget password” functionality you’ll need to make some coding for it. But because of this is something you’ll use in every project you may want to keep it as a separate plugin. Here is my solution. I have a plugin which is called sfGuardPluginExtra.

It has actions class which extens default sfGuardAuthActions class:

require_once(dirname(__FILE__).’/../../../../sfGuardPlugin/modules/sfGuardAuth/actions/actions.class.php’);
class sfGuardAuthExtraActions extends sfGuardAuthActions
{
}

And this class implements everything I may need for the most of projects: signup, password reminder, password generate functions. Also in templates folder I have overriding templates for secure, login pages.

If you have complicated user structure you may want to put into sfGuardPluginExtra/config folder schema.yml file with profile structure:

propel:
_attributes: { package: plugins.sfGuardPluginExtra.lib.model }

sf_guard_user_profile:
_attributes: { phpName: sfGuardUserProfile }
id:
user_id: { type: integer, index: unique, foreignTable: sf_guard_user, foreignReference: id, onDelete: cascade }
first_name: { type: varchar(40) }
last_name: { type: varchar(40) }
email: { type: varchar(50) }
created_at:
updated_at:

This way I may keep upgrading original sfGuardPlugin without overwriting my code and add extra functionality to sfGuardPluginExtra.

How to practically use multi-roles (groups) in sfGuardPlugin

What if you have different roles on your site, e.g. buyers and sellers? sfGuardPlugin provides “groups” as an instrument for developer to implement multi-roles functionality. So the main idea is to create plugin similar to described above sfGuardExtraPlugin. The only difference that now you may want to isolate access rights for different groups and you may do that using sfGuardBuyerPlugin/modules/sfGuardBuyer/config/security.yml

default:
is_secure: on
credentials: buyer

signup:
is_secure: off

This piece of code obviously set access restrictions for the other user groups except buyer for this module. Also it allows anyone to get access to signup action.

The other piece of code you need to use when you create a buyer user:

$user->addGroupByName(‘buyer’);
$user->addPermissionByName(‘buyer’);

It adds buyer permissions for object $user. Of course, you must have added buyer permission and buyer group in sf_guard_group and sf_guard_permissions tables.

Another trick you may be interested in – to have user logged in right after registration without entering the username/password.
So while you have $user object created this command logging this user:

$this->getContext()->getUser()->signIn($user, true);

With multi-roles you may want to have multi-enviroments. So buyer has to be logged into buyer dashboard and seller has to be logged into seller dashboard. Frankly to say I dont know good solution for it. But you may use the following technique for it:

Use sfGuardPlugin/modules/sfGuardAuth/lib/BasesfGuardAuthActions.class.php

There is executeSignin() function defined. You may do a hack right here (bad guy) or override this function in your sfGuardExtraPlugin. So the idea is to figure out user object permissions and redirect him to proper place:

e.g. add this code if ($this->getContext()->getUser()->hasCredential(‘buyer’)) $this->redirect(‘sfGuardBuyer/dashboard’);

How to implement complicated user statuses (e.g. active, pending, frozen)

This hack is going to be explained in the following articles. Keep an eye!