|
|
|
| Re: sfGuard and usage of sfGuardUserProfile [message #21408 is a reply to message #21404 ] |
Sun, 11 February 2007 23:01   |
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 #21683 is a reply to message #21432 ] |
Thu, 15 February 2007 01:03   |
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 #21843 is a reply to message #21787 ] |
Fri, 16 February 2007 20:58   |
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   |
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   |
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   |
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 #22549 is a reply to message #20465 ] |
Tue, 27 February 2007 00:07   |
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...
[Updated on: Sat, 10 March 2007 18:27] http://www.donax.ch
|
|
|
|
| Re: sfGuard and usage of sfGuardUserProfile [message #22676 is a reply to message #21884 ] |
Wed, 28 February 2007 16:48   |
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 #23404 is a reply to message #22549 ] |
Sat, 10 March 2007 18:33   |
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 #37552 is a reply to message #37550 ] |
Wed, 17 October 2007 00:22  |
 |
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
|
|
|