symfony
symfony forum
Home » plugins » General plug-ins » sfGuard and usage of sfGuardUserProfile
sfGuard and usage of sfGuardUserProfile [message #20465] Sun, 28 January 2007 11:58 Go to next message
disturbed  is currently offline disturbed
Messages: 36
Registered: April 2006
Location: Zagreb, Croatia
Member
I don't get how is sfGuardUserProfile intended to be used (in backend).
How should i connect sfGuardUserProfile and sfGuardUser?
Do i need to create new module with admin generator and configure it manually?
Re: sfGuard and usage of sfGuardUserProfile [message #20635 is a reply to message #20465 ] Wed, 31 January 2007 10:32 Go to previous messageGo to next message
jarod51  is currently offline jarod51
Messages: 79
Registered: May 2006
Member
Same for me. I don't get it to work. I've followed the "Customize the sfAuthUser model" section but it doesn't work.

I don't have my new fields when i want to create a new user. Do I need to modify a generator.yml somewhere ?

We globally need more precise information about these features Embarassed
Re: sfGuard and usage of sfGuardUserProfile [message #21404 is a reply to message #20635 ] Sun, 11 February 2007 19:28 Go to previous messageGo to next message
qube  is currently offline qube
Messages: 88
Registered: August 2006
Location: Czech republic
Member
Profile feature of sfGuardPlugin is intended to enable adding more information to user above standard username and password (etc) available in sfGuardUser.

You can create for example user table, where you want store first name, surname, email, address etc.

To connect user and sf_guard_user tables together, you must add new column (let's say sf_guard_user_id) with "foreign key to sf_guard_user" to your user table.

And then edit app.yml and add following.

all:
  sf_guard_plugin:
    profile_class:      User
    profile_field_name: sf_guard_user_id


(The reason why it cannot be done with real foreign keys is the limitation of Propel.)

Then you can access data from your user table by doing
$this->getUser()->getProfile()->getEmail();

for example.

Hope this helps.
Re: sfGuard and usage of sfGuardUserProfile [message #21408 is a reply to message #21404 ] Sun, 11 February 2007 23:01 Go to previous messageGo to next message
flat stanley  is currently offline flat stanley
Messages: 46
Registered: November 2006
Location: London
Member
I think the point that the first two posts are making is that the fields of the 'user' table are not automatically available in the generated sfGuardUser admin module.

If you want to add these fields, you would need to add partials to the sfGuardUser admin generator.yml. One for each field you want to have access to. You would then need to extend the actions and add validation. I'm not sure, but I guess that you can create a module called sfGuardUser and put your actions, partials, generator.yml and validation.yml in there, to override the built in settings.

It would be nice if this could be taken care of automatically by the admin generator, but unfortunately the generated admin modules can only handle a single table.


Antique Silver, Hester Bateman Silver, Collecting Silver
Re: sfGuard and usage of sfGuardUserProfile [message #21432 is a reply to message #21408 ] Mon, 12 February 2007 10:46 Go to previous messageGo to next message
disturbed  is currently offline disturbed
Messages: 36
Registered: April 2006
Location: Zagreb, Croatia
Member
Flat stanley, that makes sense.
Thanks...


http://i118.photobucket.com/albums/o83/disturbedHR/userbar/disturbedHR-wb.gif Dragan
Re: sfGuard and usage of sfGuardUserProfile [message #21683 is a reply to message #21432 ] Thu, 15 February 2007 01:03 Go to previous messageGo to next message
ruf79  is currently offline ruf79
Messages: 13
Registered: February 2007
Location: Lausanne, Switzerland
Junior Member
Great!
I managed to add a user profile and to show its details in the sfGuardUser module (in the "list" template) using partials.

I also managed to show the same fields in the "edit" template, but I'm not sure that these form fields point to the right database table. Anyway, also if I put something in these fields and I update/create my user, nothing is put in the sfGuardUserProfile table.

The approach explained in the symfony book ( http://www.symfony-project.com/book/trunk/14-Generators#Hand ling%20Partial%20Fields), seems not to work.

Can someone help me to create/update a user with its profile data?

Thanks!!


http://www.donax.ch
Re: sfGuard and usage of sfGuardUserProfile [message #21787 is a reply to message #20465 ] Fri, 16 February 2007 10:12 Go to previous messageGo to next message
COil  is currently offline COil
Messages: 465
Registered: September 2006
Faithful Member

The easiest way to to have an admin gen page for users and an admin gen page for profiles, in the profiles edit form just build a combo with "user_id" instead of the input.

What you could also do is to do modify the schema.yml of sfGuard to add the profile table


my Symfony Blog - http://www.strangebuzz.com
The symfony web debug bar as a standalone library : PEAR::PHP_Debug
Re: sfGuard and usage of sfGuardUserProfile [message #21843 is a reply to message #21787 ] Fri, 16 February 2007 20:58 Go to previous messageGo to next message
ruf79  is currently offline ruf79
Messages: 13
Registered: February 2007
Location: Lausanne, Switzerland
Junior Member
Yeah, I think your idea is probably the easyest to implement.

But, since I'm working on the same object ($sf_guard_user->getProfile() ), it wold be very nice to modify everything on the same page.

By the way, does someone inspected the getProfile() function? I'm a newbye in php and I don't understand if the last part of the function is there to create a profile is a new user is added:

if (!$this->profile)
      {
        $this->profile = new $profileClass();
        $method = 'set'.call_user_func_array(array($profilePeerClass, 'translateFieldName'), array($fieldName, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME));
        $this->profile->$method($this->getId());
      }


It would be nice if there was a setProfile function called automatically when creating/updating a user...


Thanks for your help


http://www.donax.ch
Re: sfGuard and usage of sfGuardUserProfile [message #21846 is a reply to message #21843 ] Fri, 16 February 2007 21:10 Go to previous messageGo to next message
flat stanley  is currently offline flat stanley
Messages: 46
Registered: November 2006
Location: London
Member
as I understand it, the user profile is created when it is first accessed.

That means you can simply set a value...

$sf_guard_user->getProfile()->setEmail('something@something')

and if this is the first time the user profile is accessed, a new profile object will be created by sfGuard behind the scenes.

Remember, you have to save the object in order for the actual database row to be created.

I guess that saving the sf_guard_user object will automatically save the associated user profile but I'm not sure. You'll have to make a test!

Good luck!


Antique Silver, Hester Bateman Silver, Collecting Silver
Re: sfGuard and usage of sfGuardUserProfile [message #21851 is a reply to message #20465 ] Fri, 16 February 2007 21:31 Go to previous messageGo to next message
flat stanley  is currently offline flat stanley
Messages: 46
Registered: November 2006
Location: London
Member
regarding your partials, you need to overide the updateXXXFromRequest action of the sfGuardUser module. I'm not sure how best to do this because you don't want to alter the contents of the plugin folder.

Maybe, create the following folder structure

app
  appname
    modules
      sfGuardUser
        actions


and copy into actions the actions.class.php file that is in the sfGuardUser module in the plugins folder.

and then add...
class userActions extends sfActions
{
  protected function updateXXXFromRequest()
  {
    // Handle the input of the partial fields
    $whatever = $this->getRequestParameter('whatever');
 
    if ($whatever)
    {
      $this->user->getProfile()->setWhatever($whatever);
    }
 
    // Let symfony handle the other fields
    parent::updateUserFromRequest();
  }
}


To find out what XXX should be, you need to look in the cached actions.class.php for the sfGuardUser module. (also, $this->user
might need changing to something else, like $this->sfGuardUser)

Good luck....

[Updated on: Fri, 16 February 2007 21:32]


Antique Silver, Hester Bateman Silver, Collecting Silver
Re: sfGuard and usage of sfGuardUserProfile [message #21856 is a reply to message #21851 ] Fri, 16 February 2007 22:17 Go to previous messageGo to next message
ruf79  is currently offline ruf79
Messages: 13
Registered: February 2007
Location: Lausanne, Switzerland
Junior Member
Thanks!!

Your suggestion seems clear! I will try and I will tell you if it worked!


http://www.donax.ch
Re: sfGuard and usage of sfGuardUserProfile [message #21884 is a reply to message #21843 ] Sat, 17 February 2007 13:42 Go to previous messageGo to next message
COil  is currently offline COil
Messages: 465
Registered: September 2006
Faithful Member

ruf79 wrote on Fri, 16 February 2007 20:58


It would be nice if there was a setProfile function called automatically when creating/updating a user...

Thanks for your help




Well in fact it's easy, just make a setProfile() in your myUser.class.php, in this one you will put the profile object in the session, call this function in sfGuardAuth sigin function... and also re-implement getProfile() in myUser to take profile from session and not from database


my Symfony Blog - http://www.strangebuzz.com
The symfony web debug bar as a standalone library : PEAR::PHP_Debug
Re: sfGuard and usage of sfGuardUserProfile [message #22549 is a reply to message #20465 ] Tue, 27 February 2007 00:07 Go to previous messageGo to next message
ruf79  is currently offline ruf79
Messages: 13
Registered: February 2007
Location: Lausanne, Switzerland
Junior Member
Hello everybody,

thanks for your posts and your suggestions. I think I have found a good solution for editing the user profile at the same time as the user itself.

Moreweb posted a ticket in the symfony trac about this problem. Can someone contact him? (See http://www.symfony-project.com/trac/ticket/964)

Here is my solution (I also attach a zip file containing my module):


Follow the official manual of the plugin (http://www.symfony-project.com/trac/wiki/sfGuardPlugin)

  • Install the plugin
  • Secure your application
  • Manage your users, permissions and groups
  • Customize the sfAuthUser model. To post an example, I created the following table in my schema.yml:
    sf_guard_user_profile:
        _attributes: { phpName: sfGuardUserProfile }
        id:
        user_id:     { required: true,  type: integer, foreignTable: sf_guard_user, foreignReference: id, onDelete: cascade }
        firstname:  varchar(20)
        lastname:   varchar(20)
    


[edit] I changed user_id columns to become a foreign key. This works on my symfony 1.0. This solves problems when loading fixtures data.

Create a sfGuardUser module

symfony init-module frontend sfGuardUser


In my case, I installed the whole plugin in my frontend, since I didn't planned to use a backend. If you plan to use your sfGuardUser module in the backend, replace "frontend" with "backend".

Create a config/generator.yml file

To start, simply copy the one in the plugin directory to your config dir:
cp $root_dir/plugins/sfGuardPlugin/modules/sfGuardUser/config/generator.yml  $root_dir/apps/frontend/modules/sfGuardUser/config  


...where $root_dir is your project root.

Then, edit the file and add/edit these lines:
generator:
  param:
    
    list:
     fields:
        name:   { name: User Name }
     display: [ =username, _name, created_at, last_login ]
        
    edit:
      fields:
        firstname: { name: First Name}
        lastname:  { name: Last Name}
      display:
        "User Profile":           [ _firstname, _lastname ]


The complete generator.yml file is available in the attached zip.

Create some template files

The _name.php, _firstname.php and _lastname.php have to be created in the templates folder:

// _name.php
// This partial is used to show the complete user name in the list action.
<?php echo $sf_guard_user->getProfile()->getFirstname().' '.$sf_guard_user->getProfile()->getLastname() ?>

// _firstname.php
// This is the first name input tag used in the edit action
<?php echo input_tag('sf_guard_user_firstname', $sf_guard_user->getProfile()->getFirstname()) ?>

// _lastname.php
// This is the last name input tag used in the edit action
<?php echo input_tag('sf_guard_user_lastname', $sf_guard_user->getProfile()->getLastname()) ?>



I choose to name my parameters sf_guard_user_firstname and sf_guard_user_lastname, but I'm not sure that it is the best solution. Can someone do better?

Anyway, these two variables must be recovered by the actions that follows. This is explaiend in the next step.

Notice that I didn't create an hidden tag with the "user_id" foreign-key, because this would lead to an empty field when creating a new user. The value will be set later, in the action part.


Edit actions/actions.class.php

Two actions have to be completed in order to save the user profile at the same time as the user itself.

The first ooperation to be performed is to load the base class that has to be overridden:

// Loading the base action to be overridden 
require_once(sfConfig::get('sf_plugins_dir').'/sfGuardPlugin/modules/sfGuardUser/lib/BasesfGuardUserActions.class.php');

class sfGuardUserActions extends BasesfGuardUserActions
{


The first function to ber overridden is updatesfGuardUserFromRequest():

protected function updatesfGuardUserFromRequest()
  {
  
    // updating user 
    parent::updatesfGuardUserFromRequest();
  
    // appending user profile data
    $firstname = $this->getRequestParameter('sf_guard_user_firstname');
    $this->sf_guard_user->getProfile()->setFirstname($firstname);
    
    $lastname = $this->getRequestParameter('sf_guard_user_lastname');
    $this->sf_guard_user->getProfile()->setLastname($lastname);  
    
  }


I call first the original function, the I append the profile details. The structure MUST be updated with all the custom fields inserted in the profile table in the db.

The last function to be overridde is savesfGuardUser. This action are generic and can be used independently from the number of fields set in the user profile table in the db:

protected function savesfGuardUser($sf_guard_user)
  {
  
  // saving user data into db
  parent::savesfGuardUser($sf_guard_user); 
  
  // getting "foreign key" field name  
  $fieldName = sfConfig::get('app_sf_guard_plugin_profile_field_name', 'user_id');

  // getting profile class
  $profileClass = sfConfig::get('app_sf_guard_plugin_profile_class', 'sfGuardUserProfile');
  $profilePeerClass =  $profileClass.'Peer';
  
  // building "setUserId" method from class and field retrieved above
  $method = 'set'.call_user_func_array(array($profilePeerClass, 'translateFieldName'), array($fieldName, BasePeer::TYPE_FIELDNAME, BasePeer::TYPE_PHPNAME));
  
  
  // recovering user profile
  $sf_guard_user_profile = $sf_guard_user->getProfile();
  
  // setting "foreign key". This operation must be done here. This is the only place where we can
  // be sure that the sfGuardUserId is set (since the user is saved/updated in the parent::savesfGuardUser).
  // A hidden field in the form wouldn't be effective when creating a new user, since its id is unknown.
  $sf_guard_user_profile->$method($sf_guard_user->getId());

  // saving user 
  $sf_guard_user_profile->save();
   
  }


In this case, first I save the user its links with groups and permissions using the original function, then I save the user profile. Since the user has been saved, an Id has been assigned and can be recovered.

The end...

I hope that this post can help someone. The next step to to is to implement testing functions to verify that everything works fine under stress.... but this is work for tomorrow... Confused


[Updated on: Sat, 10 March 2007 18:27]


http://www.donax.ch
Re: sfGuard and usage of sfGuardUserProfile [message #22614 is a reply to message #22549 ] Tue, 27 February 2007 16:25 Go to previous messageGo to next message
sfxpt  is currently offline sfxpt
Messages: 339
Registered: January 2007
Location: Canada
Faithful Member
ruf79 wrote on Mon, 26 February 2007 18:07

I think I have found a good solution for editing the user profile at the same time as the user itself.


thanks a lot for sharing!


http://xpt.sourceforge.net/techdocs/
http://xpt.sourceforge.net/tools/
Re: sfGuard and usage of sfGuardUserProfile [message #22676 is a reply to message #21884 ] Wed, 28 February 2007 16:48 Go to previous messageGo to next message
sfxpt  is currently offline sfxpt
Messages: 339
Registered: January 2007
Location: Canada
Faithful Member
COil wrote on Sat, 17 February 2007 07:42

Well in fact it's easy [to automate setting profile], just make a setProfile() in your myUser.class.php, in this one you will put the profile object in the session, call this function in sfGuardAuth sigin function...


where is the best place to put the profile object in the session?

I hacked
apps/my_app/modules/sfGuardAuth/actions/actions.class.php as:

<?php

require_once(sfConfig::get('sf_plugins_dir').'/sfGuardPlugin/modules/sfGuardAuth/lib/BasesfGuardAuthActions.class.php');

/**
 * sfGuardAuth actions.
 *
 * @package    cm
 * @subpackage sfGuardAuth
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 2692 2006-11-15 21:03:55Z fabien $
 */
class sfGuardAuthActions extends BasesfGuardAuthActions
{
  /**
   * Executes Signin action
   *
   */
    public function executeSignin()
    {
	// pre hook
  
	// call the parent method
	parent::executeSignin();
 
	// post hook
	// Store data in the user session
	$this->getUser()->
	    setAttribute('sfGuardProfileId', 
			 $this->getUser()->getProfile()->getId());
    }
}


I *thought* it's the best place, but I get the following error:

Fatal error: Call to a member function getProfile() on a non-object in /var/www/my_proj/plugins/sfGuardPlugin/lib/user/sfGuardSecur ityUser.class.php on line 193


http://xpt.sourceforge.net/techdocs/
http://xpt.sourceforge.net/tools/
Re: sfGuard and usage of sfGuardUserProfile [message #22686 is a reply to message #20465 ] Wed, 28 February 2007 18:29 Go to previous messageGo to next message
COil  is currently offline COil
Messages: 465
Registered: September 2006
Faithful Member

sfGuardAuthActions
class sfGuardAuthActions extends BasesfGuardAuthActions
{
    public function executeSignin()
    {
        if ($this->getRequest()->getMethod() == sfRequest::POST) {
            $this->setSessionDatas();
        }

        // Parent
        parent::executeSignin();
    }
    
    public function setSessionDatas()
    {
        $this->getUser()->setProfile();    	
    }


in myUser.class.php

class myUser extends sfGuardSecurityUser
{
    // Namespace
    const NS             = 'sfGuardSecurityUser';

    // Cles
    const ADMIN_MENU_KEY = 'admin_menus';
    const PROFILE_KEY    = 'profile';
    const USER_NAME_KEY  = 'user_name';
    const USER_ID_KEY    = 'user_id';
    
    ...

    public function getProfile()
    {
        return $this->getAttribute(self::PROFILE_KEY, null, self::NS);
    }

    public function setProfile()
    {
        $this->setAttribute(self::PROFILE_KEY, parent::getProfile(), self::NS);
        $this->setAttribute(self::USER_NAME_KEY, parent::getUserName(), self::NS);
    }



my Symfony Blog - http://www.strangebuzz.com
The symfony web debug bar as a standalone library : PEAR::PHP_Debug
Re: sfGuard and usage of sfGuardUserProfile [message #22692 is a reply to message #22686 ] Wed, 28 February 2007 18:57 Go to previous messageGo to next message
sfxpt  is currently offline sfxpt
Messages: 339
Registered: January 2007
Location: Canada
Faithful Member
THANKS A LOT


http://xpt.sourceforge.net/techdocs/
http://xpt.sourceforge.net/tools/
Re: sfGuard and usage of sfGuardUserProfile [message #23404 is a reply to message #22549 ] Sat, 10 March 2007 18:33 Go to previous messageGo to next message
ruf79  is currently offline ruf79
Messages: 13
Registered: February 2007
Location: Lausanne, Switzerland
Junior Member
Just to tell that I improved my patch.

I changed the user_id column to become a foreign-key of the sf_guard_user_id column.

This solves problems with loading fixtures data.

Here is an example of my data/fixtures/fixtures.yml file:


...

sfGuardUser:
  mike:
    username:       mike
    password:       ekim
    is_super_admin: false

sfGuardUserProfile:
  mike_profile:    
    user_id:    mike
    firstname:  Michael
    lastname:   Foo

...



http://www.donax.ch
Re: sfGuard and usage of sfGuardUserProfile [message #23529 is a reply to message #21787 ] Tue, 13 March 2007 14:10 Go to previous messageGo to next message
Gregr  is currently offline Gregr
Messages: 6
Registered: March 2007
Junior Member
COil wrote on Fri, 16 February 2007 10:12

The easiest way to to have an admin gen page for users and an admin gen page for profiles, in the profiles edit form just build a combo with "user_id" instead of the input.


Ok, but in this case, the admin gen will look for "UserPeer" (due to the user_id field) which doesn't exist... So how do you declare the combo of the profiles page in order it fills up with the sfGuardUsers ?

Thanks COil...

Greg
Re: sfGuard and usage of sfGuardUserProfile [message #24767 is a reply to message #20465 ] Fri, 30 March 2007 10:23 Go to previous messageGo to next message
jarod51  is currently offline jarod51
Messages: 79
Registered: May 2006
Member
Some troubles here...

If I name my profile table 'sf_guard_user_profile', i have a bunch of errors

Fatal error: Cannot redeclare class sfGuardUserProfileMapBuilder in /webs/sites/hexanet/plugins/sfGuardPlugin/lib/model/map/sfGuardUserProfileMapBuilder.php on line 5


Clearing cache does nothing

So, should I name my custom profile table something else ?

We definitely need a clear documentation on this sfGuard plugin Confused

[Updated on: Fri, 30 March 2007 10:24]

Re: sfGuard and usage of sfGuardUserProfile [message #24794 is a reply to message #24767 ] Fri, 30 March 2007 17:29 Go to previous messageGo to next message
sfxpt  is currently offline sfxpt
Messages: 339
Registered: January 2007
Location: Canada
Faithful Member
> If I name my profile table 'sf_guard_user_profile', i have a bunch of errors

Have you checked out:

[Tutorial] My Second Project - Admin Generator
http://www.symfony-project.com/forum/index.php?t=msg&th= 5064&goto=21825#msg_21825
...the docs in the sfGuard wiki has mile long gaps between them...I've been trying to follow the above and fill the gaps within.

There is a working demo of sfGuard attached in the post, in which I "didn't create the (default) sfGuardUserProfile class, but used the existing Author table for the user profile instead."

HTH


http://xpt.sourceforge.net/techdocs/
http://xpt.sourceforge.net/tools/
Re: sfGuard and usage of sfGuardUserProfile [message #32862 is a reply to message #23404 ] Sun, 05 August 2007 12:22 Go to previous messageGo to next message
lvanderree  is currently offline lvanderree
Messages: 652
Registered: June 2007
Location: Netherlands
Faithful Member
Thank you ruf79 for your example!

I have a question though, can anyone dump the content of his database? Because I see get an error now:

  [PropelException]                                         
  Cannot fetch TableMap for undefined table: sf_guard_user 


As also already mentioned here:
http://www.symfony-project.com/forum/index.php/m/32042/
and here:
http://trac.symfony-project.com/trac/ticket/2019

Maybe one of you have fixed this issue/found a way arround, or don't any of you have this problem?


Leon
Re: sfGuard and usage of sfGuardUserProfile [message #36768 is a reply to message #20465 ] Thu, 04 October 2007 14:32 Go to previous messageGo to next message
KRavEN  is currently offline KRavEN
Messages: 209
Registered: May 2007
Faithful Member
ruf79's solution is working great for me. The only issue I'm running into is I use an external authentication method so the password fields are not required.

Simply excluding them in the:

apps/app/modules/sfGuardUser/config/generator.yml

and

apps/app/modules/sfGuardUser/validate/edit.yml

does not make them go away since they were already defined in the plugin's yml files. How do I purge the plugin's yml file info before loading my custom yml files?
Re: sfGuard and usage of sfGuardUserProfile [message #37550 is a reply to message #20465 ] Wed, 17 October 2007 00:00 Go to previous messageGo to next message
phpion  is currently offline phpion
Messages: 16
Registered: July 2007
Location: Poland
Junior Member
Hi!
I've some problems with ruf79's solution. It's going on cache.
I've done everything which was shown in ruf79's example but it doesn't work (additional data (such as "surname") are NOT adding into database) Neutral Problem is cache. When I extend file /plugins/sfGuardPlugin/modules/sfGuardUser/actions/actions.c lass.php (maybe that's wrong file?) and then look into /cache/backend/dev/modules/autoUsers/actions/actions.class.p hp I don't see additional (extending) code. When I move additional code directly into cache file everything's working. But when I use "symfony cc" all modifications go away... far far away Wink

I've tried also copy generated cache code to /plugins/sfGuardPlugin/modules/sfGuardUser/actions/actions.c lass.php instade of parent::method() but then new cache file doesn't contain additional code Neutral

Tell me please what should I do...

Thanks: phpion

PS: sorry for my english Wink
Re: sfGuard and usage of sfGuardUserProfile [message #37552 is a reply to message #37550 ] Wed, 17 October 2007 00:22 Go to previous message
lvanderree  is currently offline lvanderree
Messages: 652
Registered: June 2007
Location: Netherlands
Faithful Member
I think the problem is that you copy the code from cache to your plugin folder, while you probably want to copy it to the module your have created in your application.

so instead of plugin/sfGuard../...

you copy it to apps/frontend/modules/...


Leon
Previous Topic:Warning from running sfGuardBasicSecurityFilter after clearing cache
Next Topic:[SOLVED] sfGuardPlugin and I18n Support
Goto Forum:
  

powered by FUDforum - copyright ©2001-2004 FUD Forum Bulletin Board Software