The sfGuardDoctrine Plugin
- The sfGuardDoctrine Plugin
- Description
- Installation
- Setup
- Troubleshooting
- The module "sfGuardAuth|sfGuardUser|sfGuardRegister|sfGuardForgotPassword" …
- 'Field 'permission_id' doesn't have a default value' error
- Getting the message 'Override this function in your sfGuardUserTable class …
- Using the sfGuardRegister module
- I don't like using sf_guard_user_profile, I want my own user information …
- Active tickets
Description
sfGuardDoctrinePlugin was originally a port of the propel sfGuardPlugin. It has since changed and new functionality has been added. The plugin now has 6 modules: sfGuardUser, sfGuardGroup, sfGuardPermission, sfGuardAuth, sfGuardRegister, and sfGuardForgotPassword. The plugin is still beta because of sfDoctrinePlugin still being beta, as well as Doctrine itself.
Installation
Prerequisites
symfony 1.0.x+, and the latest version of sfDoctrine are required.
Download the plugin
sfGuardDoctrine is a regular symfony plugin. Please do not install it via the command line. Currently only the subversion method is supported.
Download the plugin from svn by running:
svn co http://svn.symfony-project.com/plugins/sfGuardDoctrinePlugin/branches/symfony-1.0 sfGuardDoctrinePlugin
and place that in the plugins directory of your project. To update:
> svn update
You may also browse the source code of sfGuardDoctrine.
Setting the plugin as an svn:externals
To have the plugin updated when you do a svn update run:
> svn propedit svn:externals plugins
and type:
sfGuardDoctrinePlugin http://svn.symfony-project.com/plugins/sfGuardDoctrinePlugin/branches/symfony-1.0
Setup
Build the model
To build the Doctrine model classes for sfGuardDoctrine, run:
> symfony doctrine-build-model
Insert new tables
This will insert the tables sql for the new models you just generated. You must clear your cache first.
> symfony cc > symfony doctrine-insert-sql <app_name>
Loading Data
** WARNING! Fixtures dump/load functionality in sfDoctrine does not function 100%, use at your own risk. **
The default sfGuardDoctrine fixture is located in project/plugins/sfGuardDoctrinePlugin/data/fixtures/fixtures.yml. You should copy this file into your project data/fixtures directory to maintain the independence of the svn plugin. Another benefit of this is that you can then use your existing load_data batch file. Be sure that
create_tables: true
is set in your doctrine.yml (this is the default).
Remaining Setup
sfGuardDoctrine follows an identical setup to sfGuardPlugin, you can follow all instructions there after the propel-specific instructions, which end with:
> symfony propel-load-data
near the top of the page.
Troubleshooting
The module "sfGuardAuth|sfGuardUser|sfGuardRegister|sfGuardForgotPassword" is not enabled.
For some reason (at least for me), the enabled_modules instructions given on the sfGuardPlugin page don't work.
all:
.settings:
enabled_modules: [default, sfGuardAuth]
is ignored, I had to explicitly set these same values for each environment i was using them in. so:
dev:
.settings:
enabled_modules: [default, sfGuardAuth]
worked for myapp_dev.php/login.
'Field 'permission_id' doesn't have a default value' error
if you get the following error when loading the default sfGuardDoctrine fixture:
>> Filling class "sfGuardUserGroup"
.
[Doctrine_Connection_Mysql_Exception]
SQLSTATE[HY000]: General error: 1364 Field 'permission_id' doesn't have a default value
there is a simple fix. change:
sfGuardGroupPermission:
adminGroupPermission:
sfGuardGroup: adminGroup
sfGuardPermission: adminPermission
to:
sfGuardGroupPermission:
adminGroupPermission:
sfGuardPermission: adminPermission
sfGuardGroup: adminGroup
to avoid this foreign-key-related error.
Getting the message 'Override this function in your sfGuardUserTable class so it queries for the user based on the username or email address'
After generating the default model you also need to add this function 'retrieveByUsernameOrEmailAddress' to the generated sfGuardUserTable.class.php in your own application directory, so it will override the default plugin's function. NEVER change it in the plugin directory itself, because you will lose your changes after updating.
Using the sfGuardRegister module
If you want to use the sfGuardRegister you'll have to create a module with the same name in your application's modules directory (easiest is to do symfony init-module appname modulename) and extend it. Do not forget to include the BasesfGuardRegisterActions? class.
I don't like using sf_guard_user_profile, I want my own user information available
This can be done very easily and with doctrine it will only create one query which is very nice.
Override the getGuardUser() function in myUser.class.php
class myUser extends sfGuardSecurityUser
{
public function getGuardUser()
{
if ( !$this->user && $id = $this->getAttribute( 'user_id', null, 'sfGuardSecurityUser' ) )
{
$q = new Doctrine_Query();
$q->select('s.*, u.*, p.*, p2.*, a.*, a2.*');
$q->from('sfGuardUser s');
$q->leftJoin('s.User u');
$q->leftJoin('u.Phone p')->leftJoin('p.PhoneType p2');
$q->leftJoin('u.Address a')->leftJoin('a.AddressType a2');
$q->where('s.id = ?', $id);
$this->user = $q->execute()->getFirst();
if ( !$this->user )
{
// the user does not exist anymore in the database
$this->signOut();
throw new sfException( 'The user does exist anymore in the database.' );
}
}
return $this->user;
}
}
You'll notice I have User, Phone, PhoneType?, Address, AddressType? as tables for each of my users. I have my schema.yml file looking like this. I'll only show the abbreviated User, Phone, and PhoneType?. Address is the same as Phone
User:
tableName: user
columns:
prefix: string(5)
first_name: string(20), notblank: true
middle_name: string(20)
last_name: string(20), notblank: true
suffix: string(10)
company: string(45)
date_of_birth: date, notblank: true
updated_at: timestamp
created_at: timestamp
sf_guard_user_id:
foreignClass: sfGuardUser
foreignName: sfGuardUser
localName: User
cascadeDelete: true
unique: true
Phone:
tableName: phone
columns:
user_id:
foreignClass: User
foreignName: User
localName: Phone
cascadeDelete: true
phone_type_id:
foreignClass: PhoneType
foreignName: PhoneType
localName: Phone
number: string(20)
extension: string(10)
is_primary: boolean
updated_at: timestamp
created_at: timestamp
Phone:
tableName: phone
columns:
user_id:
foreignClass: User
foreignName: User
localName: Phone
cascadeDelete: true
phone_type_id:
foreignClass: PhoneType
foreignName: PhoneType
localName: Phone
number: string(20)
extension: string(10)
is_primary: boolean
updated_at: timestamp
created_at: timestamp
Now when ever you need information about the logged in user you can simply call in the template:
sfGuardUser Username: <?php echo $sf_user->getUsername() ?> <br /> User First Name: <?php echo $sf_user->getGuardUser()->User->getFirstName() ?> Phone Numbers: <?php foreach($sf_user->getGuardUser()->User->Phone as $phone): ?> Phone Type(__toString(), going to be name): <? echo $phone->getPhoneType(); ?> Phone Name: <? echo $phone->getNumber(); ?> Phone Extension: <? echo $phone->getExtension(); ?> <?php endforeach; ?>
Active tickets