3

My setup: I am on Drupal 7 but not using the default user profile pictures; instead, I have a custom image field, profile_picture, which is attached to the user profile. When users register, they must select their gender (Male/Female/Prefer not to say).

I would like to assign a different default picture to this profile_picture field based on the value each user selects for gender. I tried using Set a data value with Rules but I can't figure out how to get these three specific pictures (one for each gender choice) to be options.

If it helps, each user also has a role based on their gender. I'm not committed to using Rules for this; I will accept any solution that allows me to reliably set the picture based on the value of the field in their profile. There is no opportunity for users to change their gender so this needs only be set once.

EDIT: Users are later able to replace this with their own custom profile picture, so I need to keep this as an Image field.

  • D6 or D7? Is your profile_picture field a text field that points to a path or is it a file field? – Jimajamma Jul 22 '12 at 6:15
  • D7, and I'm using an Image field (D7 core). Question updated. – Patrick Kenny Jul 22 '12 at 7:08
2
+100

A simple approach might be to retheme the gender field itself so that it displays an image based upon its value, eg, instead of displaying male, it displays an image with path sites/default/files/male.png.

In D6, this would mean copying CCK's content-field.tpl.php to your theme directory and then creating content-field-field_gender.tpl.php and jiggering things up in there, eg...

print theme('image', 'sites/default/files/' . $item['view'] . '.png')

...instead of just print $item['view'].

My quick look at D7 here suggests that copying Field's field.tpl.php to field--gender--profile.tpl.php in your theme's directory would be basic starting point there and instead of render()ing $item, doing something similar with its value.

Then, in either version, just make sure you have three images in your files directory called male.png, female.png and unknown.png (or files based upon whatever the values of your gender field are.)

With this approach, you only have three files to deal with instead of a file uploaded and stored for each and every user. Another side benefit is that they will be easily cached by your users' browsers.

ADDITION:

Based upon new info from comments and other answers, you could do something like this in your user-picture.tpl.php template:

if (!empty($account->field_profile_picture[LANGUAGE_NONE][0]['fid'])) {
  // Load the file
  $file = file_load($account->field_profile_picture[LANGUAGE_NONE][0]['fid']);

  // Note the style name is "profile_picture" as explained in your question,
  // not "profile_pic" which was in your original code
  echo theme('image_style', array('style_name' => 'profile_picture', 'path' => $file->uri));
} else {

  $file_path = 'sites/default/files/' . $account->field_gender[LANGUAGE_NONE][0]['value'] . '.png';
  echo theme('image_style', array('style_name' => 'profile_picture', 'path' => $file_path));

}

where the new stuff is the else .... Pardon my D6ism if sites/default/files is wrong in D7, but basically you just want a path on your system to where you've stuck male.png, female.png and unknown.png and you display them when your profile_picture field is not set.

  • Thanks for this approach. However, users are later able to replace this default profile picture with a custom picture of their own choosing, so I need to have a separate field for each user, and I need it be this field that is displayed as the picture. Sorry about the confusing wording on the original question. – Patrick Kenny Jul 22 '12 at 8:32
  • gotcha. I'll post something else after the morning espresso kicks in :) – Jimajamma Jul 22 '12 at 12:44
2

One way is to add a custom submit handler for user registration form.

   function yourmodule_form_alter(&$form, &$form_state, $form_id) {
        if ($form_id == 'user_register_form') {
            $form['#submit'][] = 'mycustom_user_profile_form_submit';
        }
    }

And then assign value to your profile_picture field programmatically as below.

function mycustom_user_profile_form_submit($form, &$form_state) {
    if ($form ['field_gender']['und']['#value'] == "Male") {
        $image_path = 'public://pictures/male.jpg';
    } else if ($form ['field_gender']['und']['#value'] == "Female") {
        $image_path = 'public://pictures/female.jpg';
    } else if ($form ['field_gender']['und']['#value'] == "Prefer not to say") {
        $image_path = 'public://pictures/other.jpg';
    }
    $result = db_query("SELECT f.fid FROM {file_managed} f WHERE f.uri = :uri", array(':uri' => $image_path));
    $record = $result->fetchObject();
    $image_info = image_get_info($image_path);
    $fid = 0;
    $account = user_load($form_state['values']['uid']);

    //check if file is already in file_managed table
    if ($record) {
        $fid = $record->fid;
    } else {

        //create new file
        $file = new StdClass();
        $file->uid = $account->uid;
        $file->uri = $image_path;
        $file->filemime = $image_info['mime_type'];
        $file->status = 0;
        $file->filesize = $image_info['file_size'];
        file_save($file);
        $fid = $file->fid;
    }

    //create file array
    $file_array = array();
    $file_array['fid'] = $fid;
    $file_array['display'] = 1;
    $file_array['height'] = $image_info['height'];
    $file_array['weight'] = $image_info['width'];


    $account->field_profile_picture['und'][0] = $file_array;

    user_save($account);
}
1

You can use hook_field_attach_submit() as this hook is invoked after the field module has performed the operation.

A fully implemented code is as follows

/**
 * Implements hook_field_attach_submit().
 */
function MODULE_NAME_field_attach_submit($entity_type, $entity, $form, &$form_state) {

    // First find the image fields. This proces is much more complicated than
    // it probably should be.
    // 1. Grab the name of the entity bundle
    // 2. Grab the list of fields for the given entity type and bundle
    // 3. Loop through all fields in that type and bundle and get the image
    //    fields names.
    $entity_info = entity_get_info($entity_type);

    // User entity doesn't have a bundle. So you just pass the type into the
    // bundle field.
    if (empty($entity_info['entity keys']['bundle'])) {
        $field_instances_info = field_info_instances($entity_type, $entity_type);
    }
    else {
        $field_instances_info = field_info_instances($entity_type, $entity->{$entity_info['entity keys']['bundle']});
    }

    $image_fields = array();

    foreach ($field_instances_info as $field_name => $field_instance_info) {
        if($field_name == 'field_profile_picture') {
            $field_info = field_info_field($field_name);
            $image_fields[$field_name] = $field_instance_info['settings'];
            $image_fields[$field_name]['uri_scheme'] = $field_info['settings']['uri_scheme'];
            $image_fields[$field_name]['empty'] = ($form[$field_name]['und'][0]['#value']['fid'] > 0)? FALSE:TRUE;
            $image_fields[$field_name]['default_images_path'] = "default_images";
            $image_fields[$field_name]['gender'] = $form['field_gender']['und']['#value'];

        }
    }
    // The list of image fields is now available. If the instance setting of that
    // field has random_default set and the image field is empty choose a random
    // file of the supported file type in the directory.
    foreach ($image_fields as $field_name => $field_instance_info) {
        if ($field_instance_info['empty']) {

            if($field_instance_info['gender'] == 'Male') {
                $file_selection = cf_get_image_info("public://default_images/avatar-male.jpg");
            }
            else {
                $file_selection = cf_get_image_info("public://default_images/avatar-female.jpg");

            }

            // 2. Check if a file id exists for it
            $result = db_select('file_managed', 'fm')
                ->fields('fm', array('fid'))
                ->condition('fm.uri', $file_selection['uri'])
                ->execute()
                // Fetch as array
                ->fetchAll(PDO::FETCH_ASSOC);

            // 3. If it does not create a new one
            if (empty($result)) {
                GLOBAL $user;
                $file = new stdClass();
                $file->uid = $user->uid;
                $file->filename = $file_selection['filename'];
                $file->uri = $file_selection['uri'];
                $file->filemime = file_get_mimetype($file_selection['uri'], $mapping = NULL);
                $file->status = 1;

                file_save($file);
            }
            else {
                $file = file_load($result[0]['fid']);
            }

            // Add a fake file usage to prevent files pulled form the random directory
            // from being deleted when they are no longer referenced.
            $usage = file_usage_list($file);
            if (!isset($usage['profile_default_image'])) {
                file_usage_add($file, 'profile_default_image', 'profile_default_image', 0);
            }

            // 4. Identify this file for the field
            $entity->{$field_name}['und'][0] = (array) $file;
        }
    }
}


function cf_get_image_info($path) {
    $image1 = image_get_info($path);
    $image2 = pathinfo($path);
    $image_info = array_merge($image1, $image2);
    $image_info['uri'] = $path;

    return $image_info;
}
0

How about overriding template_preprocess_user_picture()?

--> Here's the default implementation: http://api.drupal.org/api/drupal/modules%21user%21user.module/function/template_preprocess_user_picture/7

Notice this is where the decision is made to use an image supplied by the user or to fall back to a default picture:

[...]

elseif (variable_get('user_picture_default', '')) {
  $filepath = variable_get('user_picture_default', '');
}

[...]

You could simply extend that to interrogate the gender field present in the $account object (which is available at that time) and provide a user_picture_default_male and user_picture_default_female.

Does that make sense?

  • That makes sense, but I'm already overriding the user picture template as explained here: drupal.stackexchange.com/questions/27005/… Can I use the same technique in the template file? I don't understand how to specify the locations of the files in PHP. – Patrick Kenny Jul 22 '12 at 10:33
  • yes, you can use the same template file by adding the additional logic that checks for a populated profile image. If none is found, then display the gender specific one. – Jason Smith Jul 25 '12 at 15:42
0

Another Solution: ( using profile 2 ) create user-picture.tpl.php in your theme folder then try the below code.

<?php if ($user_picture) {?>
<div class="<?php print $classes; ?>">
    <?php print $user_picture; ?>
</div>

    <?php 


} else {
$profile = profile2_load_by_user($account->uid);


global $language ;
$curr_lang = $language->language;

if ($profile['main']->field_user_gender) {
$field_user_gender = $profile['main']->field_user_gender['und'][0]['value'];
$uid = $profile['main']->uid;

}
if($field_user_gender=="female"){
?>

        <div class="user-picture">
            <a href="/<?=$curr_lang?>/user/<?=$uid?>" class="active"><img src="/sites/all/themes/xxx/img/f.jpg"></a>

        </div>
        <?php }else{?>
            <div class="user-picture">
                <a href="/<?=$curr_lang?>/user/<?=$uid?>" class="active"><img src="/sites/all/themes/xxx/img/m.jpg"></a>
            </div>
            <?php
}
} ?>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.