I'm not a programmer at all, but I've already done some small changes in the code...
I've learned that to get an user field, for instance email, I should use $user->email. However, it looks like it doesn't work for my own custom profile fields.
If I have myfield, I can't call it through $user->myfield. What is the correct sintax to call it then????
Thanks for any help!
Hugs from Leticia
In reply to Leticia Maimann-Roland
Re: How do I get a custom profile field in the code?
Well, all I need is display 2 of my custom profile fields in the table that appears when we click in 'browse list of users'.
I've seen in ...user/profile/lib.php that all the custom fields are gotten together in a table. I want, however, just 2 of my custom fields to be shown. They are the only ones in a category, so I was thinking that maybe if I used function profile_display_fields($userid) to display just one category it could solve my problem.
I'm still just a little bit confused with that function, so any help is welcome!
Hugs from Leticia
I've seen in ...user/profile/lib.php that all the custom fields are gotten together in a table. I want, however, just 2 of my custom fields to be shown. They are the only ones in a category, so I was thinking that maybe if I used function profile_display_fields($userid) to display just one category it could solve my problem.
I'm still just a little bit confused with that function, so any help is welcome!
Hugs from Leticia
In reply to Leticia Maimann-Roland
Re: How do I get a custom profile field in the code?
by Shane Elliott -
Hi Leticia,
I haven't tested this code but inserting something like the following should do the trick:
Hope that helps.
I haven't tested this code but inserting something like the following should do the trick:
... require_once($CFG->dirroot.'/user/profile/lib.php'); profile_load_data($user); if (!empty($user->myfield)) { echo $user->myfield } ...where $user is a valid user object. The function profile_load_data adds the data in the custom profile fields to the user object. Warning: If there is no data then the field is not set.
Hope that helps.
Hi. I am really confused over the custom fields, and how to change them with code. I can't seem to get help with this on some of the other forums, then I ran across your discussion. Here is my problem:
I have a custom field I set up with the admin account for all users, called "status". I set it to a default value of "new".
If I use the $USER variable, I can see the value with:
print $USER->status;
That prints out "old". This seems to counter the experience of you guys in this thread. I never have a problem reading the value this way.
What I have encountered is that I can't change the value of the status field in the database. Of course teh following line only changes the value in the session variable:
$USER->status = "old";
$_SESSION['USER']=$USER; // do this to update $SESSION with the new data
If I do the following however, I can of course update the value of the other regular fields in the database, say firstname:
$USER->firstname = "newname";
So being new I reported the "bug" of the custom variable not updating, got a swift response from Eloy about how the custom fields are stored in a different table, and to use the profile_save_data().
Well, I can't seem to make either the profile_save_data OR profile_load_data work. I am very perplexed. Shouldn't the following give me the value of my status field too?
require_once($CFG->dirroot.'/user/profile/lib.php');
// section on custom variables
print "<BR>Starting custom variables output<BR>";
$myuser = new object();
profile_load_data($myuser);
if (!empty($myuser->status)) {
print $myuser->status;
}
else {
print "myuser->status was empty";
}
print "<BR>Ending custom variables<BR>";
I always get an empty value. Conversely, when I try to use the profile_save_data I can't make it work, no matter what variation I try to use, such as below:
Simply doing the following does not work:
$USER->status = "old";
profile_save_data($USER);
I even tried to load them first with:
//Load custom profile fields data
profile_load_data($myuser);
and then set the value with:
$myuser->status = "old";
and then save it with:
profile_save_data($myuser);
That does not work.
This is something I really want to tackle, as I am working on a system to provide new users (e.g. the default value for the status field is "new" when they are created as a user) with help instructions, that then go away after they see it (e.g. the status field for them is set by code to "old")
Any suggestions are appreciated - or is there a better programming manual or something that I am just overlooking. Thanks,
Jamie
I have a custom field I set up with the admin account for all users, called "status". I set it to a default value of "new".
If I use the $USER variable, I can see the value with:
print $USER->status;
That prints out "old". This seems to counter the experience of you guys in this thread. I never have a problem reading the value this way.
What I have encountered is that I can't change the value of the status field in the database. Of course teh following line only changes the value in the session variable:
$USER->status = "old";
$_SESSION['USER']=$USER; // do this to update $SESSION with the new data
If I do the following however, I can of course update the value of the other regular fields in the database, say firstname:
$USER->firstname = "newname";
So being new I reported the "bug" of the custom variable not updating, got a swift response from Eloy about how the custom fields are stored in a different table, and to use the profile_save_data().
Well, I can't seem to make either the profile_save_data OR profile_load_data work. I am very perplexed. Shouldn't the following give me the value of my status field too?
require_once($CFG->dirroot.'/user/profile/lib.php');
// section on custom variables
print "<BR>Starting custom variables output<BR>";
$myuser = new object();
profile_load_data($myuser);
if (!empty($myuser->status)) {
print $myuser->status;
}
else {
print "myuser->status was empty";
}
print "<BR>Ending custom variables<BR>";
I always get an empty value. Conversely, when I try to use the profile_save_data I can't make it work, no matter what variation I try to use, such as below:
Simply doing the following does not work:
$USER->status = "old";
profile_save_data($USER);
I even tried to load them first with:
//Load custom profile fields data
profile_load_data($myuser);
and then set the value with:
$myuser->status = "old";
and then save it with:
profile_save_data($myuser);
That does not work.
This is something I really want to tackle, as I am working on a system to provide new users (e.g. the default value for the status field is "new" when they are created as a user) with help instructions, that then go away after they see it (e.g. the status field for them is set by code to "old")
Any suggestions are appreciated - or is there a better programming manual or something that I am just overlooking. Thanks,
Jamie
I am replying to my last post with some progress to report.
Instead of using the profile_load_data() I foudn the profile_user_record() and that is now retrieving the custom fields into a variable. The following now prints the value of "status":
// section on custom variables
print "<BR>Starting custom variables<BR>";
$myuser = new object();
//profile_load_data($myuser);
$myuser = profile_user_record($USER->id);
if (!empty($myuser->status)) {
print $myuser->status;
}
else {
print "myuser->status was empty";
}
Now I am trying to use that new variable $myuser to update the field value - but still no luck:
$myuser->status = "old";
profile_save_data($myuser);
The value of "status" does not change, and so far I can't find an alternative in the cross reference.
Instead of using the profile_load_data() I foudn the profile_user_record() and that is now retrieving the custom fields into a variable. The following now prints the value of "status":
// section on custom variables
print "<BR>Starting custom variables<BR>";
$myuser = new object();
//profile_load_data($myuser);
$myuser = profile_user_record($USER->id);
if (!empty($myuser->status)) {
print $myuser->status;
}
else {
print "myuser->status was empty";
}
Now I am trying to use that new variable $myuser to update the field value - but still no luck:
$myuser->status = "old";
profile_save_data($myuser);
The value of "status" does not change, and so far I can't find an alternative in the cross reference.
Hi Jamie,
Looking through /user/edit.php and /user/profile/lib.php it appears profile_load_data() and profile_save_data() both access custom settings with a prefix of 'profile_field_'
So that would be why it is not saving.
Hope this helps,
Aaron
Looking through /user/edit.php and /user/profile/lib.php it appears profile_load_data() and profile_save_data() both access custom settings with a prefix of 'profile_field_'
So that would be why it is not saving.
Hope this helps,
Aaron
Thanks Aaron,
I am looking at the two functions which should give me similar results. The first one below does not work for at all. The second one below does work for me:
I am looking at the two functions which should give me similar results. The first one below does not work for at all. The second one below does work for me:
282 function profile_load_data(&$user) { 283 global $CFG; 284 285 if ($fields = get_records_select('user_info_field')) { 286 foreach ($fields as $field) { 287 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 288 $newfield = 'profile_field_'.$field->datatype; 289 $formfield = new $newfield($field->id, $user->id); 290 $formfield->edit_load_user_data($user); 291 } 292 } 293 } 397 /** 398 * Returns an object with the custom profile fields set for the given user 399 * @param integer userid 400 * @return object 401 */ 402 function profile_user_record($userid) { 403 global $CFG; 404 405 $user = new object(); 406 407 if ($fields = get_records_select('user_info_field')) { 408 foreach ($fields as $field) { 409 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 410 $newfield = 'profile_field_'.$field->datatype; 411 $formfield = new $newfield($field->id, $userid); 412 if ($formfield->is_user_object_data()) $user->{$field->shortname} = $formfield->data; 413 } 414 } 415 416 return $user; 417 } The two functions are almost exactly the same, except for lines 290 and 412. Of course profile_user_record returns $user back to me, and that does seem to have the correct fields in it. For instance, I can do a $user->status to get the value that I set from the user's profile. The first function nevers works for me. I have tried to pass it a new object called $myuser, as well as the whole $USER and it never works either way :-( And of course the following is what really kills me - the saving does not work: 347 function profile_save_data($usernew) { 348 global $CFG; 349 350 if ($fields = get_records_select('user_info_field')) { 351 foreach ($fields as $field) { 352 require_once($CFG->dirroot.'/user/profile/field/'.$field->datatype.'/field.class.php'); 353 $newfield = 'profile_field_'.$field->datatype; 354 $formfield = new $newfield($field->id, $usernew->id); 355 $formfield->edit_save_data($usernew); 356 } 357 } 358 } I really am at a loss...
Finally figured out how to write data value back into a custom user profile field in the database 
This was a sometimes frustrating experience, but in the end I learned a lot! I am putting my findings down here in case anyone else needs to alter the value of one of these fields using php code:
First, my example works on a field called "status" that I added using the
That is the function. I called it with the following:
$anewstatus = "old6";
print "Next step is save_status passing it anewstatus= ".$anewstatus." for userid= ".$myid."<BR>";
if (!save_status($myid, $anewstatus)) {
print "save_status failed<BR>";
} else {
print "save_status worked<BR>";
}
I will briefly describe why I think the built-in functions like profile_save_data were not doing it for me. First, I was confused by the built-in session variable $USER, which shows the values for that login session. It cane give you the value of fields such as $USER->firstname or even custom fields like $USER->status; however, this profile_ functions are not directly messing with a $USER variable or one like it. The cross reference has parameters passed to them with names like "newuser", but if you dig deeper you will see how these work. Also, the custom fields are wisely stored in a different table, that is accessed using two tables actually. Use the database add-on module phpmyadmin to get you the really vital database screens that show you all the tables, etc. The tables involved are called user_info_data and user_info_field.
Another stumbling block for me was the fact that those functions all seemed to work around a form that you see when you edit them in teh normal profile edit screen. Well, that confused matters for me. I finally had success when getting down to lower level functions, that BTW were well documented
Also, thank you to everyone who offered hints and encouragement in this post and other related posts I made.
For the begineer who is testing things, the way you run things is put the code in a page that you can call as a web page from your site. I followed some advice on some other forum posts and created a folder in your main moodle folder system. This is at the level of folders such as block and theme. Make a folder there called tests. Put the php you want to test in a file with extension .php, such as custom.php . You may have to change the permissions to rw-rw-r-- to be able to execute it. To run it, go to your site URL and put in the path to the file, like www.afakemoodlesite.com/tests/custom.php
If you are logged in, you will see the results of all the print statements. The log in checking code stops everyone except logged in users so visitors and guests can't see this run. You might dump variables that have passwords and inner workings of your site, which could cause a security risk. I would do this when you have no other users registered, such as when you are building and testing a site. When you are done, you can always rename the file so it doesn't have the .php at the end.
I hope this helps everyone who wants to write a value to a custom field,
Good luck!
Jamie
PS I am attaching my custom.php file, as an example. Note it is still full of commented out tests and other debug stuff, but it will show you a good real-world example.
This was a sometimes frustrating experience, but in the end I learned a lot! I am putting my findings down here in case anyone else needs to alter the value of one of these fields using php code:
First, my example works on a field called "status" that I added using the
administration-users-accounts-user profile fieldsIn my case, I intend to have a block that looks at a user's status field, if it is "new" (the default value I set up when a new user if created), then a "welcome aboard" screen is presented with an orientation video, etc. After that first viewing, I want to set the status to "old" so they never have that screen show up again. I tried all sorts of functions, like profile_save_data(), but had problems. Finally just printing all session variables and going over and over again each function, I was able to debug my issue. Deeper inside the profile_save_data function and other related ones is a function called edit_save_data() and also update_record(). I was able to make my own function called save_status() which I documented below. Note that I have all sorts of debug print lines, as well as comments. This was what I just developed, and I will be taking this and refining it for my block next week. However, I left it all in so you can see what is happening. Here is the code:
function save_status($theuserid, $newstatus) {
// write a new value for the custom profile field "status" which i manually
// added for all the users using the administration-users-accounts-user profile fields
// pass it the userid of the user to change, plus the new text value
$data = new object();
$data->userid = $theuserid; // who to do this too
$data->fieldid = 2; // status happens to be fieldid 2 from the table user_info_data
// note this could be different depending on other custom fields
// check the fieldid using the administration database tool
//$data->id is the record specific field id set below
$data->data = $newstatus; // use the text value passed as parameter above
print "debug - save_status: data->userid= ".$data->userid." data->fieldid= ".$data->fieldid." data->data= ".$data->data."<BR>"; //debug
// first get the id number of this record from the user_info_data, could be anything
if ($dataid = get_field('user_info_data', 'id', 'userid', $data->userid, 'fieldid', $data->fieldid)) {
// must have gotten the id number of it so now store back to it
$data->id = $dataid; // store the returned specific id number in the data object
print "debug - found the data->id = ".$dataid."<BR>"; // debug
// now update the record with it all
if (!update_record('user_info_data', $data)) {
print "debug - there was error with update_record so no save<BR>"; // debug
return false;
} else {
// aok
return true;
}
} else {
// must not have found any record in the table for that combination
print "debug - no record was found for that combination so no save<BR>"; // debug
return false;
}
}
That is the function. I called it with the following:
$anewstatus = "old6";
print "Next step is save_status passing it anewstatus= ".$anewstatus." for userid= ".$myid."<BR>";
if (!save_status($myid, $anewstatus)) {
print "save_status failed<BR>";
} else {
print "save_status worked<BR>";
}
I will briefly describe why I think the built-in functions like profile_save_data were not doing it for me. First, I was confused by the built-in session variable $USER, which shows the values for that login session. It cane give you the value of fields such as $USER->firstname or even custom fields like $USER->status; however, this profile_ functions are not directly messing with a $USER variable or one like it. The cross reference has parameters passed to them with names like "newuser", but if you dig deeper you will see how these work. Also, the custom fields are wisely stored in a different table, that is accessed using two tables actually. Use the database add-on module phpmyadmin to get you the really vital database screens that show you all the tables, etc. The tables involved are called user_info_data and user_info_field.
Another stumbling block for me was the fact that those functions all seemed to work around a form that you see when you edit them in teh normal profile edit screen. Well, that confused matters for me. I finally had success when getting down to lower level functions, that BTW were well documented
Also, thank you to everyone who offered hints and encouragement in this post and other related posts I made.
For the begineer who is testing things, the way you run things is put the code in a page that you can call as a web page from your site. I followed some advice on some other forum posts and created a folder in your main moodle folder system. This is at the level of folders such as block and theme. Make a folder there called tests. Put the php you want to test in a file with extension .php, such as custom.php . You may have to change the permissions to rw-rw-r-- to be able to execute it. To run it, go to your site URL and put in the path to the file, like www.afakemoodlesite.com/tests/custom.php
If you are logged in, you will see the results of all the print statements. The log in checking code stops everyone except logged in users so visitors and guests can't see this run. You might dump variables that have passwords and inner workings of your site, which could cause a security risk. I would do this when you have no other users registered, such as when you are building and testing a site. When you are done, you can always rename the file so it doesn't have the .php at the end.
I hope this helps everyone who wants to write a value to a custom field,
Good luck!
Jamie
PS I am attaching my custom.php file, as an example. Note it is still full of commented out tests and other debug stuff, but it will show you a good real-world example.
Hi Jamie,
Sorry I missed your forum post - been away a bit recently.
The simple answer is that the custom profile fields are stored in the $user data object with "profile_field_" prefixed. So the short solution should be something like the following:
Cheers,
Shane.
Sorry I missed your forum post - been away a bit recently.
The simple answer is that the custom profile fields are stored in the $user data object with "profile_field_" prefixed. So the short solution should be something like the following:
profile_load_data($user); $user->profile_field_status = 'newstatus'; profile_save_data($user);Hope that helps.
Cheers,
Shane.
Hi Shane,
Thanks for the follow-up. However, I still can't make your approach work. I am attaching a status.php script that I execute from a test folder.
It can't get a value from the line:
print "profile_field_status found at ".$theuser->profile_field_status."<BR>"; // try another
It also does not change the value in the database. I wrote it so that it would toggle the value of a custom field called "status" from "new" to "old" to "new" and so on.
If you could test and tell me if my system is messed up or something, that wold help me.
Also, when I look at the database tables, I see all the values stored in something called mdl_user_info_data, with the custom field definitions in the table mdl_user_info_field. I don't see any reference to "profile_field_". Was wondering if maybe the changed the table names recently?
Anyway, thanks for any help or insight on this,
Jamie
Thanks for the follow-up. However, I still can't make your approach work. I am attaching a status.php script that I execute from a test folder.
It can't get a value from the line:
print "profile_field_status found at ".$theuser->profile_field_status."<BR>"; // try another
It also does not change the value in the database. I wrote it so that it would toggle the value of a custom field called "status" from "new" to "old" to "new" and so on.
If you could test and tell me if my system is messed up or something, that wold help me.
Also, when I look at the database tables, I see all the values stored in something called mdl_user_info_data, with the custom field definitions in the table mdl_user_info_field. I don't see any reference to "profile_field_". Was wondering if maybe the changed the table names recently?
Anyway, thanks for any help or insight on this,
Jamie
Hi Jamie,
You need to pass in a valid user object to profile_load_data not an empty object. With an empty object it won't know which user you are referring to. So
for your code sample something like the following:
You need to pass in a valid user object to profile_load_data not an empty object. With an empty object it won't know which user you are referring to. So
for your code sample something like the following:
require_login();
print "USER->status = $USER->status<br />"; // to see the session variable
$theuser = clone($USER);
profile_load_data($theuser);
I realise the values already exist in the $USER object without "profile_field_" prefixed but when working with the data it is currently necessary to load them up, edit and save with the prefixed values in order to avoid duplications with standard profile fields ie it would be a problem if there was a custom profile field called "username"
Cheers,
Shane.
Hi Shane!!!!!
I am so excited, as it is now working. I wasn't familiar with the clone command at all, and I think that was what hung me up earlier in my tests. I see that came out with PHP5, which I am using... but my experience with PHP programming per se was with 4 (been doing Python for past years so have had to adjust my thinking to do my customization work on Moodle
Using your suggetsion above, I was able to get my test script status.php (attached) to work 100%. I really appreciate the assistance. Now I can use that to set status to make that "welcome page/video" block appear once, when they first login to the site!
Thanks again,
Jamie
I am so excited, as it is now working. I wasn't familiar with the clone command at all, and I think that was what hung me up earlier in my tests. I see that came out with PHP5, which I am using... but my experience with PHP programming per se was with 4 (been doing Python for past years so have had to adjust my thinking to do my customization work on Moodle
Using your suggetsion above, I was able to get my test script status.php (attached) to work 100%. I really appreciate the assistance. Now I can use that to set status to make that "welcome page/video" block appear once, when they first login to the site!
Thanks again,
Jamie