Posted by tolland76 on October 9, 2009 at 9:08am
Hi all,
During registration I have a module that calls hook_user and creates a new node and writes some values to it. Some of those values come from my Profile fields such as profile_postcode and profile_number.
However the profile_postcode and profile_number fields are null in the $edit var during hook_user, and if I do;
$user = user_load(array('uid'=>$account->uid));
$profile = profile_load_profile($user);
the user object comes back, but with no profile_postcode or profile_number values in it.
Any ideas what I can do to access those values?
Thanks,
Tom
Comments
I think you should
EDIT:
I'm sorry, I misread your question. It seems you want to create a node using profile module fields during user registration. You probably want to use $edit[profile_postcode] and $edit[profile_number] instead of $user->profile_postcode, since $user object isn't populated as there is no $user->uid yet.
Unfortunately, I wasn't able to access $edit[profile_*] values during registration. I'm not sure why, but they come out empty during registration (I might be doing something wrong though).
This is what I found from experience:
In hook_user, you have several operations ($op). Those operations take place in a certain order.
During $op = 'insert' (registration), $user (or $account) object is empty since user has not been created yet. Drupal first reads the form fields needed and then saves them to database, creating a new entry. Since $user->uid value is basically a database primary key, it makes sense drupal saving the values first and only hten populate the $user object with the right $user->uid value.
During $op= 'load' you can update $user object.
During $op= 'update' $user object is available but its not updated. It retains the old values (before the user filled those fields and clicked "submit").
I'm not sure what happens first, if it is op='load' or op='insert', but from experience, it seems load comes first. Either way, in pratical terms, during 'insert' $user object is empty, during 'update' it's outdated.
Regarding user module and profile module, it seems to happen like this:
Drupal read fields necessary for {user} table and creates a new row.
Then it retrieves that user uid and populates {user_profile} table with that uid as foreign key and the profile module fields.
It makes sense since {user} is the main table and {user_profile} is the linked table, joined by the uid.
Somewhere along the way, the $edit[profile_*] fields are deleted (I found that in profile module source code) It seems when a module invokes hook_user, those fields are are already empty. Maybe if you can make your module have precedence over profile module, those $edit fields still exist when your module invoke hook_user.
The only way I could work around this was creating registration fields programatically, using hook_form_alter and envelop my code in a conditional using $form_id as argument.
Something like this:
function mymodule_form_alter(&$form, $form_state, $form_id) {
if ( ($form_id == 'user_profile_form' && arg(3) == NULL) ||
($form_id == 'user_register') ) {
$n_user = user_load(arg(1));
$form['mymodule'] = array(
'#type' => 'fieldset',
'#title' => t('Personal Information'),
'#description' => t(''Your Personal Information.),
);
$form['mymodule']['firstname'] = array(
'#type' => 'textfield',
'#title' => t('First Name'),
'#default_value' => $n_user->firstname,
'#size' => 60,
'#maxlength' => 255,
'#description' => t('Your First Name'),
'#required' => TRUE,
);
}
}
then invoke hook_user and use $edit['firstname'] to retrieve what the user wrote in the field firstname.
Hope it helps.
---------------------------------------------------------
Center for Research and Creativity in Informatics
---------------------------------------------------------
Alternative solution
I've also encountered the issue of not being able to access profile fields during the hook_user 'update' operation. The profile variables are indeed stripped out care of profile.module (line 245 as of present Drupal 6 version I'm using).
My solution is to call in the user object during my hook_user 'update' operation to use as a comparison between the old user object provided in $account with the profile fields inserted already care of profile.module's hook_user update function.
<?php
function modulename_user($op, &$edit, &$account, $category = NULL) {
switch($op){
case "update":
$profile_user = user_load(array('uid'=>$account->uid)); // user object with profile fields already applied
//$account has the pre-update $user object for comparison
// do stuff here (see <a href="http://drupal.org/node/1214878" title="http://drupal.org/node/1214878" rel="nofollow">http://drupal.org/node/1214878</a> for ideas on how to update hidden profile fields)
break;
}
}
?>
sydneyshan
Enigma Digital, Australia
Another Way
You can also load the fields from the profile module (core) with:
profile_load_profile($account);
The $account object is passed to the function via reference so the profile fields are added to the object, so you would use something like:
$account->your_field_name;
if your are using the content_profile module, you can use:
$profile = content_profile_load('profile', $account->uid);
then something like:
$last_name = $profile->field_profile_last_name[0][value];
Mark
A new way to get the update profile fields in hook_user update
The profile module will only load the profile values with profile_load_profile if they are not already set. Aside from the fact that there should be a way to pass a 2nd parameter of TRUE to override them if you want to, this code in my hook_user update op allowed me to access profile values in hook_user:
foreach ($account as $key => $value) {if (substr($key, 0, 7) == 'profile') {
unset($account->$key);
}
}
profile_load_profile($account);
I also changed my module to be heavier than profile but not sure if that is necessary or not.