Hello,

I noticed a profile picture is only imported if a new account is created on Drupal, but not when user links an existing Drupal account with FB.

The code responsible for this is in
fbouath.fboauth.inc, the function importing pics is in fboauth_create_user

    // If the user is already logged in, associate the two accounts.
    if ($user->uid) {
      fboauth_save($user->uid, $fbuser->id);
      drupal_set_message(t('You\'ve connected your account with Facebook.'));
    }
    // Register a new user only if allowed.
    elseif (variable_get('user_register', 1)) {
      $account = fboauth_create_user($fbuser);
CommentFileSizeAuthor
#14 fboauth-1440346-1.patch1.68 KBallabakash.g

Comments

quicksketch’s picture

Yep, that's correct. Right now we only add user pictures on registration, not on connecting existing accounts. I'd be happy to review any patches for this feature request.

jay.lee.bio’s picture

I'd like to see this feature added too. :D

grasmash’s picture

I needed this feature and implemented it in a custom module. I've made the module available in sandbox mode here: http://drupal.org/sandbox/madmatter23/1493630

I'm toying with the idea of releasing this module, but at the moment I think that it has too few features and too narrow a scope.

gittosj’s picture

I've managed to prove that my php skills are not sufficient to write a decent patch but here's some hints to save time for anyone who's more skilled than me and can have a go:

The code we need to tweak in in fboauth/includes/fboauth.fboauth.inc and the code that saves the facebook picture to a user's profile is in a block from lines 204 to 227. My instinct is that we should change add a function around line 87 and 95 to retrieve and save the picture (there's no need to do complex user array loads or saves since the 204-227 code writes straight to the database.

Any takers?

gittosj’s picture

My experience is that this is a very important issue. Ordinary users are now more and more used to seeing their facebook picture pop up on sites and it gives them some comfort and thrill (!) when it happens. Its a clear visual pointer that they are logged in - my user testing shows that most of them think that no photo means that they're not logged in. Equally 20-30% of users wil register in the normal drupal way and then come back and use the Facebook login button - often because its easier than remembering their password.

So my hacky solution is to add the picture code to a custom php login block (top right corner of header in my case). This displays links and the user's picture. If the user has no picture then it pulls it in from facebook and saves it if not already there - if this is a big security / performance issue then do let me know! Block content is below and input format set to php code:

<?php
global $user;
$account = user_load($user->uid); //load user, all user fields & fbuid
$fbid=fboauth_fbid_load(); //load the facebook id

//dpm($user); // uncomment this if you want to see the krumo output & variables of $user
//dpm($account); // uncomment this if you want to see the krumo output & variables of $account

print ('<div class="user_details">');
    if ($user->uid == 0){ //not logged in
        print ('<div class="user_login">'.l(t('Login') , 'user/login').'</div>');
        print ('<div class="user_signup">'.l(t('Signup for Yoursitesname') , 'user/register').'</div>');
        //print fboauth_action_display('connect');
        print ('<div class="user_fb_login">'.fboauth_action_display('connect').'</div>');
        }

// If the user is logged & has a picture then display it
    else {
    print('<div class="user_pic">');
    if(!is_null($account->picture)){
        $attr = array(
        'style_name' => 'slider_thumb',
        'path' => $account->picture->uri,
        'width' => '50',
        'height' => '50',
         );
        print theme('image_style', $attr);
     }

// Or if the picture field is empty then pull in a picture from Facebook
elseif (isset($fbid)) {
    $picture_directory =  file_default_scheme() . '://' . variable_get('user_picture_path', 'pictures');
    if(file_prepare_directory($picture_directory, FILE_CREATE_DIRECTORY)){
      $picture_result = drupal_http_request('https://graph.facebook.com/' . $fbid . '/picture?type=large');
      $picture_path = file_stream_wrapper_uri_normalize($picture_directory . '/picture-' . $account->uid . '-' . REQUEST_TIME . '.jpg');
      $picture_file = file_save_data($picture_result->data, $picture_path, FILE_EXISTS_REPLACE);

      // Check to make sure the picture isn't too large for the site settings.
      $max_dimensions = variable_get('user_picture_dimensions', '85x85');
      file_validate_image_resolution($picture_file, $max_dimensions);

      // Update the user record.
      $picture_file->uid = $account->uid;
      $picture_file = file_save($picture_file);
      file_usage_add($picture_file, 'user', 'user', $account->uid);
      db_update('users')
        ->fields(array(
        'picture' => $picture_file->fid,
        ))
        ->condition('uid', $account->uid)
        ->execute();
 }
// echo ('Saved a new picture'); //used for testing
}

     print('</div>');

// print links for logout & edit user etc - dpm (see above will tell you what else is avaiable)

        print ('<div class="right_details">');
        print ('<div class="user_edit">'.l(t('Account Settings') , 'user/'.$user->uid.'/edit').'</div>');
        print ('<div class="user_mail">'.t($account->mail).'</div>');
        print ('<div class="user_logout">'.l(t('Logout') , 'user/logout').'</div></div>');
         }

print ('</div>');

?>

And the css that goes with it:

div.user_details
{
 font-size: 87.5%;
 position: relative;
 float: right;
 margin: 21px 21px 10px 0;
 clear: both;
 overflow: visible;
 width: auto;
}

div.user_details div.user_pic
{
 float: left;
 clear: none;
 overflow: auto;
 position: relative;
 width: auto;
 margin-right: 10px;
}

div.user_details div.right_details
{
 float: right;
 clear: right;
 margin: 0 0 0 10px;
}

div.user_details div.user_fb_login
{
 margin: 10px 0 0 0;
 float: right;
 clear: right;
}

div.user_details .user_login,
div.user_details .user_signup,
div.user_details .user_name,
div.user_details .user_edit,
div.user_details .user_mail,
div.user_details .user_logout
{
 float: right;
 clear: right;
 margin: 0;
}


gittosj’s picture

Actually thinking about it, this would be much better done as a rule that fires on login.

So create a new rule that fires on 'User has logged in'

with an action set to 'Execute custom PHP code'

and paste this into the php code box:

global $user;
$account = user_load($user->uid); //load user, all user fields & fbuid
$fbid=fboauth_fbid_load(); //load the facebook id

//dpm($user); // uncomment this if you want to see the krumo output & variables of $user
//dpm($account); // uncomment this if you want to see the krumo output & variables of $account

// Check if the logged in user has a picture saved & has linked their FB account through fboauth
   if(is_null($account->picture) && !empty($fbid)) {
    $picture_directory =  file_default_scheme() . '://' . variable_get('user_picture_path', 'pictures');
    if(file_prepare_directory($picture_directory, FILE_CREATE_DIRECTORY)){
      $picture_result = drupal_http_request('https://graph.facebook.com/' . $fbid . '/picture?type=large');
      $picture_path = file_stream_wrapper_uri_normalize($picture_directory . '/picture-' . $account->uid . '-' . REQUEST_TIME . '.jpg');
      $picture_file = file_save_data($picture_result->data, $picture_path, FILE_EXISTS_REPLACE);

      // Check to make sure the picture isn't too large for the site settings.
      $max_dimensions = variable_get('user_picture_dimensions', '85x85');
      file_validate_image_resolution($picture_file, $max_dimensions);

      // Update the user record.
      $picture_file->uid = $account->uid;
      $picture_file = file_save($picture_file);
      file_usage_add($picture_file, 'user', 'user', $account->uid);
      db_update('users')
        ->fields(array(
        'picture' => $picture_file->fid,
        ))  
        ->condition('uid', $account->uid)
        ->execute();
 }
//echo ('Saved a new picture'); //used for testing
}

Tested it quite a bit and it seems to cover all scenarios - pulls the users FB picture in as they log in, as long as they already have a picture and have associated their FB account though fboauth. Let me know if you find any bugs or issues

pontusgustafsson’s picture

Testing, and seems to work just fine! Thanks!

asheeshjoshi’s picture

Hi... this code works great for me. However there is an issue which I am not able to understand if it is because of this code...

I have posted the issue here http://drupal.org/node/1850544

Do you know what could be causing this ? I have not changed anything else in Facebook oAuth module.

asheeshjoshi’s picture

Never mind. I was able to resolve the issue. Its fixed. And thanks once again for your php script. It works great.

imoreno’s picture

#6 work very well for me, thank you gittosj!

hartogsmith’s picture

very helpful -- thanks for your time, effort and brains!

mrded’s picture

Guys, check out patch from #2101595: Profile picture from Facebook
It should solve your problem.

imoreno’s picture

code in #6 is a bit unstable.
while it does import the picture on connect, the site tend to "forget" it and not really store it on the appropriate user field.

so once you visit couple of pages the image is not showing anymore.

any ideas why?

BR
Itzhak

allabakash.g’s picture

Component: Miscellaneous » Code
Issue summary: View changes
Status: Active » Needs review
StatusFileSize
new1.68 KB

with reference to #6, instead of Rule, i have updated in the code, it worked!

darrellduane’s picture

Status: Needs review » Reviewed & tested by the community

I can confirm that #14 worked. I can now get photos from Facebook to come directly into Drupal's picture for each user that joins the site via FBOauth.

darrellduane’s picture

Status: Reviewed & tested by the community » Patch (to be ported)

This is in the dev version of this module as of October 2014.

  • DarrellDuane committed 8dadd05 on 7.x-1.x
    The following four issues were added in a previous commit but...
darrellduane’s picture

Version: 7.x-1.x-dev » 7.x-1.7
Status: Patch (to be ported) » Closed (fixed)