I'm importing users from another DB. I can create the user object and save it just fine. I'm just wondering how to populate the profile fields now.

Comments

mmilano’s picture

Figured it out:

  // create profile object
  $profile = profile_create(array('user' => $account, 'type' => 'main'));

  // populate profile fields
  $profile->field_firstname['und'][0]['value'] = 'John';
  $profile->field_lastname['und'][0]['value'] = 'Smith';
  $profile->field_gender['und'][0]['value'] = 'M';

  // save profile
  profile2_save($profile);
joachim’s picture

Title: How do you programmatically create profile info? » Add to documentation: How do you programmatically create profile info?
Category: support » feature

Assuming we have documentation pages, it'd be really useful if you had time to add that to a page, or start a new one on working with profile2 programatically :)

ubdr’s picture

what does $profile->field_firstname['und'][0]['value'] denotes ?

dan3h’s picture

'und' means "undefined language". See Gábor's post about it

Note that for clarity, you can/should use drupal's constant, LANGUAGE_NONE instead of the string 'und'. So...
$profile->field_firstname[LANGUAGE_NONE][0]['value']

dan3h’s picture

If you doing this to import users, you can use the User Import Framework (which is where I learned about 'und'). It's a nice balance of pre-written module, and hooks for you as a programmer to import your data how you want.

fago’s picture

you can also use the entity API wrappers, e.g. this is what Rules uses.

southweb’s picture

// Create a profile type; add a field; populate it.

   profile2_type_save(new ProfileType(array(
      'type' => 'timetracker',
      'label' => 'Profile for Timetracker Users',
      'weight' => 0
    )));
    
    // Add a field to main type, which is created during module installation.
    $field = array(
      'field_name' => 'fullname',
      'type' => 'text',
      'cardinality' => 1,
      'translatable' => FALSE,
    );
    field_create_field($field);
    $instance = array(
      'entity_type' => 'profile2',
      'field_name' => 'fullname',
      'bundle' => 'timetracker',
      'label' => 'Full name',
      'description' => 'Specify your first and last name.',
      'widget' => array(
              'type' => 'text_textfield',
        'weight' => 0,
      ),
    );
    field_create_instance($instance);

  // create/load profile object
  
  $profile = profile2_by_uid_load($user->uid,"timetracker");
  if (!$profile){
      $profile = profile_create(array('user' => $user, 'type' => 'timetracker'));
      $profile = profile2_by_uid_load($user->uid,"timetracker");
  }
      
  // populate profile fields
   $profile->fullname[LANGUAGE_NONE][0]['value'] = 'John Wayne';

  // save profile
   profile2_save($profile);
bxCreative’s picture

Great stuff - thanks for this.

PS - for version 7.x-1.1, function profile2_by_uid_load should be profile2_load_by_user.

pwaterz’s picture

Status: Active » Closed (fixed)

I dont think this needs to be in the documentation. I dont even think node module has documentation on how to programmatically create nodes. Also it's pretty straight forward if you have worked with creating any entity programmatically.

zulfierken’s picture

Sorry to open again.
I am trying to update profile2 field programmatically. Using:
$main_profile->field_name[LANGUAGE_NONE][0]['value'] = $form_state['values']['name'];
$saved_profile = profile2_save($main_profile);
works great and change the value.
At the other hand this does not change the safe_value. Should I add one more line to change safe value also (if this is the case why there is safe value :) )
For now, adding
$main_profile->field_name[LANGUAGE_NONE][0]['safe_value'] = $form_state['values']['name']; is enough or not? Are there any other places that I should change.

I think profile update function should update related fields including safe values automatically.

pwaterz’s picture

I believe you need to add the safe value as well. This has nothing to do with the profile module. It has to do with fields api.

derherrberger’s picture

Thx mmilano, your post helped me a lot!

A little update: in Profile2 Version 7.x-1.2 the function profile_create() is marked as "Deprecated. Use profile2_create()." (profile2.module Line 278)

ludo.r’s picture

In my opinion, a better way to populate profile fields would be :

  $fields = array(
    'field_firstname' => 'John',
    'field_lastname' => 'Doe',
    'field_link_website' => 'http://www.johndoe.com',
    'field_secondary_email' => 'jd@johndoe.com',
  );
  //Create/load profile object 
  if (!$profile = profile2_load_by_user($user->uid, 'personal')) {
    $profile = profile2_create(array('user' => $user, 'type' => 'personal'));
    profile2_save($profile);
  }
  //Populate profile fields
  $wrapper = entity_metadata_wrapper('profile2', $profile->pid);
  foreach($fields as $field_name => $value) {
    $wrapper->{$field_name}->set($value);
  }
  $wrapper->save();

So that you don't care about setting fields specificities like :

$profile->field_firstname[LANGUAGE_NONE][0]['value'] = 'John';
$profile->field_link_website[LANGUAGE_NONE][0]['url'] = 'http://www.johndoe.com';
$profile->field_secondary_email[LANGUAGE_NONE][0]['email'] = 'http://www.johndoe.com';

NB : I have tested with textfields, but not with link or email fields, it may require an array as a value to set.

swim’s picture

Just a side note to profile2 field population. When updating field data from a profile object make sure you reference the desired profile type when saving.

global $user;
$profile = profile2_load_by_user($user);
$profile['main']->field_webform['und'][0]['value'] = 'node/' . $form['#node']->nid;
// Main being our profile type.
profile2_save($profile['main']);

Fairly obvious ofc but hopefully it helps.

daveX99’s picture

Title: Add to documentation: How do you programmatically create profile info? » Notes re: code in #7

[edited to fix name of function in #1, below... -davex99]
[edited a 2nd time to remove extra closing parenthesis in code block... -davex99]
The code above (#7) was very helpful, but I have 3 quick comments with regards to how to create/load profile object:

  1. As noted in another comment (#12), the function 'profile2_by_uid_load' is deprecated, and has been replaced by 'profile2_load_by_user', which is passed a user object, not just the uid. You can also specify the type, or leave it out if you want an array of all profiles for that user
  2. The call to 'profile_create' should be 'profile2_create'.
  3. I used the code from above to try and populate a profile field for a user who did not yet have that profile set up for themselves. It generated an error: "Recoverable fatal error: Argument 1 passed to profile2_save() must be an instance of Profile, instance of stdClass given..."
    I think this is because of the call to load the profile AFTER creating it, but not yet having saved it -- it loads an empty object.
    So, instead, my version of that code looks like this:
    $profile = profile2_load_by_user($user, 'some_profile_type');
    if (!$profile) {
      $profile = profile2_create(array('user' => $user, 'type' => 'some_profile_type'));
    }
    $profile->field_foo_bar_blah['und'][0]['value'] = 123;
    profile2_save($profile);
    

    Also, FWIW, I did not have to set the 'safe_value' of the field array - setting the 'value' was enough, but I was setting an integer value.

-dave.

joachim’s picture

thirstysix’s picture

Thanks.