This has been a big topic since FB has changed their TOS to allow for extended permissions to be saved IF and only the user authorized your app.. When they authorize your app they will now see all the various extended permissions your asking for.

the key idea to syncing accounts between drupal and fb is to be able to get these extended permissions data. A patch was created to add the extended permissions to the FB app module and can be found here. http://drupal.org/node/867242

What is missing is the ability to extend the drupal profile fields to capture this data if authorized and remove them when the user removes the app (I think thats part of the TOS as well)

something like profile_hometown for example would store the home town data from FB into drupal..

I would be willing to work with some people to put something together and have looked over the loop where it stores the users email and username... but I have limited time right now, however I figured I would capture this request since its a pretty requested feature for Durpal FaceBook module

Comments

Anclywen’s picture

Field storage:
Maybe instead of the profile module, we will use Content profile module

I do not like the profile, it hurts me, lack of imagefield and filefield.
But the combined power of CCK & Views, when you can handle files, not mention to using with other content types (Views).

Synchronization:
In order not to quarrel, it seems to me that it would be better to leave at administrator's discretion.
In some cases just once an hour, some every 3 minutes.

Unfortunately, you can't use Cron, because in most cases we need to make synchronization when user is not using your application (or application must have permission offline_access)

Dave Cohen’s picture

Title: Facebook extended permission to update drupal user profile fields » Update drupal user profile fields with data from facebook

I agree this is a great feature to have! I haven't tried to implement anything along these lines, in part because it was originally a violation of facebook's terms of service. I also see it as pretty complicated. For example, should values only be copied from facebook, or synced (two-way)? How does one map a value from facebook to a profile field (i.e. does the drupal field have to have exactly the same name used on facebook?)

If you want to build a module to work specifically with one third-party module, like Content Profile Module, or CCK, I welcome that but I think it should be done as it's own standalone module. That is, not part of modules/fb, but use modules/fb as a dependency.

If you want to build a module that works more generically, supporting drupal's core profile module or using drupal_execute() to save the values regardless of how they are stored on Drupal, then I would consider adding it to modules/fb (or possibly modules/fb/contrib).

Either way I'll do my best to help, but don't at the moment have any real time to work on this myself.

gateway69’s picture

StatusFileSize
new84.21 KB

I figured I would take a bit of time to map out some thoughts (check included image) on how this could work and be flexible enough for people who want to use drupal profile or other.

I think one of the issues at hand is some might want to use default profile and other content profile or even a custom cck type, which I think is valid, I for one am using Advance Profile Kit on a few of my sites but use regular drupal profile on others.

with that said I think it might be solved by using the extended permissions names from the FB side of thigns.. like for example:

user_location
user_photo
User_relationships

and defining what those are for example

user location --> cck field location , or just a normal text field (location field might be to advanced for now)
user_photo --> image-field
user_relationships --> text field

Of course to keep it simple it might be valid to only use maybe the default cck types that come with cck and maybe image-field

Then on the drupal admin side of things we have a separate tab called extended permissions. which allows you to create a new one lets say App Test123, then I select the permissions I want to enable, time to sync (keep things in sync) and a pull down of drupal profile or content profile...

by selecting one of the proper defined fields (which needs to be defined first for all permissions) get inserted into content types..

Then save.. .now when I create a new app, I can instead of having permissions their select from a pull down of created permissions from the other admin section...

on the user side of things, they should be able to remove the app, remove all permissions, or even go down to having the ability to just turn or uncheck home_town which then removes this from the drupal profile..

anyhow easier said than done but just some thoughts.. mind map included ...

Anclywen’s picture

Next idea:

It seems to me that we need an API that will be was between Facebook and other contributed modules.

API will be responsible for:
- Cyclic retrieval of data from facebook (and then calling hook_fb_synchronisation_check_field )
- Changing data on facebook (API function called by other modules)
- A invoke to remove all data (hook_fb_synchronisation_remove_all_fields() ) or specific fields
- check required permissions

At first glance, we need to create: //function names are examples, probably will be changed

  • fb_synchronisation_change_field($uid, $field_name, $value) // Called by the modules, in order to change the value on facebook
  • fb_synchronisation_get_fields($app_id) // Get all available fb's fields to map to the corresponding module's fields
  • hook_fb_synchronisation_check_field($uid, $field_name, $field_value) // Synchronisation fb -> contributed modules
  • hook_fb_synchronisation_remove_all_fields() // Calling to empty all values are kept
  • hook_fb_synchronisation_remove_field($field_name) // Calling to empty one particular field, eg. as a result of remove permission

Mapping fields:

Mapping fields is done directly in the module. You can get all available fb's fields via fb_sychronisation_get_fields($app_id)

Synchronisation:

  • facebook -> Drupal
    API invoke hook_fb_synchronisation_check_field($uid, $field_name, $value), and the contributed modules update the value (if necessary)
  • Drupal -> facebook
    Module call fb_synchronisation_change_field($uid, $field_name, $value) and can update field in the FB

Removing data:

On demand, API should invoke hook_fb_synchronisation_remove_all_fields() or hook_fb_synchronisation_remove_field($field_name)

Advantages Solutions:

Fields can be saved in any way (Profile, CCK, etc.) (by creating standalone module)
Mapping and maintenance depends on contributed module.

What we need:

Name and describe every field in the FB, together with its type (text, int image, array (text))
Eg.

  • mail (text - 128 chars)
  • home_location (text - 128 chars)
  • photo (image)

Standalone or fb/contrib
As Dave suggests, I'll create CCK integration as standalone module.
I'm not sure, which is better, profile integration as standalone module or in fb/contrib (after all it's a core module)

--
A bit much, but I hope is quite clear :)

gateway69’s picture

nice.. sounds like some attack plans are made.. :)

Anclywen’s picture

StatusFileSize
new40.62 KB
new40.03 KB
new15.03 KB
new13.57 KB

Because picture is worth thousand words (and my English is a bit rusty :) ), some battle maps

Anclywen’s picture

I've found something really interesting - FB Real-time Updates

Whenever a subscribed change occurs, Facebook makes an HTTP POST request to an endpoint you specify with a list of changes. A real-time server will generally send you notification of the change within a couple of minutes of its occurrence.

Of course it have some limitations:

List of user connections to which you can subscribe:

feed, friends, activities, interests, music, books, movies, television, likes, statuses, links

You can't subscribe to these user connections yet:

home, tagged, posts, photos, albums, videos, groups, likes, notes, events, inbox, outbox, updates, accounts

And ...

We will add support for those connections in the coming days. If you are interested, please check back on this page at later time for updates.

gateway69’s picture

any movement on this, I'm holding off on FB module for now since I just cant get it to do what I need for a new game we are working on, I'm in the process of writing some custom code that will when a user on FB auths the app, ill write the FB data to the drupal custom profile with the data that im requesting from FB.. the only issue I'm facing right now is when FB user doesnt have a drupal account how do i create one on the fly and assign or link it to the custom profile?

Dave Cohen’s picture

Take a look at fb_user.module. It creates a drupal account, links it using the authmap table. It even invokes hook_fb after creating the account so you could put your code in that hook.

At some point, I'm planning to use a new table instead of authmap. But for now at least, authmap is where the local account is linked to the facebook account.

gateway69’s picture

thanks ill give that a shot, what would be the minimum install for the facebook drupal i would need, i guess i mean the which modules do i need. So far I created a content profile type with the permissions and extended permissions data i want to store, when the user hits the page and allows, i want wanted to do a db insert into that table with all the fb data, I guess then your saying I could use the fb_user.module to create an account for that person also?

RasputinJones’s picture

Actually wrote this yesterday. Updates content profile fields with data from fb retrieved using FQL. This isn't production ready but thought I should share...


function _fb_module_after_build($form, &$form_state)  {
    $fb = $GLOBALS['_fb'];

    $query = "SELECT first_name, middle_name, last_name, email, pic_big_with_logo FROM user WHERE uid = me()";
    $access_token = array('auth_token' => $fb->getAccessToken);

    // fql
    $result = fb_fql_query($fb, $query, $access_token);

    $form['group_about_me']['field_user_firstname'][0]['value']['#value'] = $result[0]['first_name'];
    $form['group_about_me']['field_user_firstname'][0]['#value']['value'] = $result[0]['first_name'];

    $form['group_about_me']['field_user_middle'][0]['value']['#value'] = $result[0]['middle_name'];
    $form['group_about_me']['field_user_middle'][0]['#value']['value'] = $result[0]['middle_tname'];


    $form['group_about_me']['field_user_lastname'][0]['value']['#value'] = $result[0]['last_name'];
    $form['group_about_me']['field_user_lastname'][0]['#value']['value'] = $result[0]['last_name'];

    $form['group_about_me']['field_user_email'][0]['value']['#value'] = $result[0]['email'];
    $form['group_about_me']['field_user_email'][0]['#value']['value'] = $result[0]['email'];

    $form['group_about_me']['field_user_profile_image'][0]['value']['#value'] = $result[0]['pic_big_with_logo'];
    $form['group_about_me']['field_user_profile_image'][0]['#value']['value'] = $result[0]['pic_big_with_logo'];

    return $form;
}

/**
* Implementation of hook_form_alter.
*
* Adds a checkbox to node edit and comment forms.  This checkbox lets
* facebook users know that content may be published to their Wall,
* and gives them a chance to prevent that.
*/
function fb_module_form_alter(&$form, $form_state, $form_id) {
   if (isset($GLOBALS['_fb']) && fb_facebook_user()) {  // will be set if user logged using facebook connect
     switch($form_id)   {
         case 'node_form':
             $form['dff_custom']['stream_publish'] = array(
               '#type' => 'checkbox',
               '#title' => 'Share your review with your friends on Facebook',
               '#default_value' => TRUE,
             );
             break;
         case 'comment_form':
            $form['dff_custom']['stream_publish'] = array(
                '#type' => 'checkbox',
                '#title' => 'Share your review with your friends on Facebook',
                '#default_value' => TRUE,
            );
            break;
         case 'profile_node_form';
            $form['#after_build'][] = '_fb_module_after_build';
            break;
     }
  }
}

Dave Cohen’s picture

I think you're better off using hook_form_alter() to pre-populate the default values.

Also, you shouldn't name your module "fb_module" because "fb_..." is essentially reserved by modules/fb. I recommend "custom_fb" or "mysite_fb".

gateway69’s picture

wow sweet.. we should get this incorporated into the FB module or a separate plugin..

ST

RasputinJones’s picture

Dave thanks for the feedback. The reason I used after build was because these were CCK fields in Content Profile. It's very hard to update these in hook_form_alter.

The module's actual names is mysite_fb. I just took off identifying information...:)

gateway69’s picture

i did something a bit different.. its outside of the fb drupal module since im doing most coding by scratch for our game, but if you pass in a fb uid and app id, you can save data to the content profile module.. Probably not the best way to do this since im still learning the drupal api system.

  // Add a user to our database aka hes a new game player.
  // Will need to make sure we do not do this test on every page
  function addfacebookdata($fbme,$app_id){
	  
	// if the user is valid and has a proper access_token
	if($fbme) {
		
		// standard facebook permission settings + email extended permission 
		// can be easly expanded
		// this data will be inserted into the user database if fb_uid isnt already used
		$fb_uid       		=   $fbme['id'];
		$first_name      	=   $fbme['first_name'];
		$last_name       	=   $fbme['last_name'];
		$email	       		=   $fbme['email'];
		$link       		=   $fbme['link'];
		$location	       	=   $fbme['location']['name'];
		$gender	       		=   $fbme['gender'];
		$dateupdated		=	$fbme['updated_time'];
		$application_id		=   $app_id;
					
		// query node field for type category and make sure status = 1 (active)
		$results = db_query("SELECT field_fb_uid_value FROM content_type_profile WHERE field_fb_uid_value = $fb_uid");
		
		if (db_affected_rows($result) == 0){
			  $data = array(
				'vid'  					=> '1',
				'nid'					=> $fb_uid,		
				'field_fb_uid_value' 	=> $fb_uid,       		
				'field_fb_first_name_value'	=> $first_name,    	
				'field_fb_last_name_value'	=> $last_name,      
				'field_fb_email_email'	=> $email,	       		
				'field_fb_link_value'	=> $link,       	      
				'field_fb_gender_value'	=> $gender,	       
				'field_fb_app_id_value'	=> $application_id,
				'field_fb_location_value'	=> $location,
				'field_fb_date_value'	=> $dateupdated
			  );
			 
			 // debug data 
			 d($data);
			 
			 // add user_save drupal function to create a valid user account and link it to the uid of fb
			 $details = array(
			  'name' => $first_name . $last_name,
			  'pass' => user_password(),
			  'access' => 1, // optional, i didnt want user to be able to this this account yet
			  'status' => 1,
			  'init' => $email,
			  'roles' => array(3 => 'gamer'), // Current role in drupal thats assigned to people playing the game.
			  'fbuid' => $fb_uid
			);

			// Mail available only if user has granted extended permission.
			if (isset($email)) {
			  
			  $details['mail'] = $email;
				} else {
				
				$details['mail'] =  $fb_uid."@facebook.com";
			}
			
			// drupal function to save a new user, can also be used to update
			$user = user_save(null, $details);
			
			// debug
			//d($user);
			
			$profile_node = new stdClass();
			$profile_node->body = '';
			$profile_node->type = 'profile';   // Your specified content type
			$profile_node->created = $time;
			$profile_node->changed = $time;
			$profile_node->status = 1;
			$profile_node->promote = 0;
			$profile_node->sticky = 0;
			$profile_node->format = 1;       // Filtered HTML
			$profile_node->uid = $user->uid; // UID of content owner
			$profile_node->field_fb_uid[0]['value'] = $fb_uid;
			$profile_node->field_fb_first_name[0]['value'] = $first_name;
			$profile_node->field_fb_last_name[0]['value'] = $last_name;
			$profile_node->field_fb_email[0]['email'] = $email;
			$profile_node->field_fb_link[0]['value'] = $link;
			$profile_node->field_fb_gender[0]['value'] = $gender;
			$profile_node->field_fb_app_id[0]['value'] = $application_id;
			$profile_node->field_fb_location[0]['value'] = $location;
			$profile_node->field_fb_date[0]['value'] = $dateupdated;
			$profile_node->field_uid[0]['value'] = $user->uid;
			
			node_save($profile_node);

			} 
		}	
  }

ST

g.k’s picture

subscribing

westis’s picture

subscribing

ceriamy’s picture

Title: Update drupal user profile fields with data from facebook » drupal for facebook has been nicely installed - then what?

drupal for facebook has been nicely installed and all modules seems to give me no problem. But I'm confused about what else to be done, there is nothing appearing in my drupal site, no Facebook Log-in icons, no Facebook connect icons, no "like" icon in my drupal site. The installation document stops at completing installation, but then what? What should be done after that?

Dave Cohen’s picture

Title: drupal for facebook has been nicely installed - then what? » Update drupal user profile fields with data from facebook
g.k’s picture

I'm also learning the Drupal APIs. Can you please provide some information on where you added the function and how to call the function I would like to pull the data from Facebook and update content profile during initial registration and if possible, during linking of user's local account (already registered used) through Facebook connect.

ckng’s picture

Title: Update drupal user profile fields with data from facebook » Update drupal user profile fields with data from facebook

Here are some thoughts on mapping the data without putting restriction on certain modules. Well, except one, the Rules module, optionally if only user need to get more FB data. The only need is to create FB events when it happens and we can conveniently tap into Rules existing facility to validate, populate fields (including CCK), update the node, etc.

These events can be triggered when user connect with FB, on demand or using FB real-time.
#907706: Rules module integration, we probably only need the following events
- fb_user_connected = User has connected his FB account
- fb_user_disconnected = User has disconnected his FB account
- fb_user_login = User has logged in via FB

and some sample rules..

gorgo’s picture

subscribing

bunker’s picture

++subscribing :-)

monicadear’s picture

subscribing - I'd like to work on integrating Facebook with Advanced Profile Kit.

Bobuido’s picture

Good idea. Subscribing.

c0m4’s picture

Title: Update drupal user profile fields with data from facebook » subscribing
c0m4’s picture

Title: subscribing » Update drupal user profile fields with data from facebook

subscribing

rumblewand’s picture

subscribing

vlad.k’s picture

subscribing

stieglitz’s picture

subscribing

jjjames’s picture

following

pribeh’s picture

subscribing.

FergalMohan’s picture

subscribing.

zabelc’s picture

Since my users only keep their Facebook profiles up to date this would be a fantastic feature. Did any of the thoughts from last October come to any results?

johnla’s picture

subscribing..

I'll share if I get anywhere.. Thanks for sharing your progress, fellas

escore’s picture

If anyone has more time than me, here's how I've been thinking about cutting and pasting it (nothing has been tested):

function mymodule_fb_user($op, $data, &$return) {
  $fb_app = isset($data['fb_app']) ? $data['fb_app'] : NULL;
  $fb = isset($data['fb']) ? $data['fb'] : NULL;
  $account = isset($data['account']) ? $data['account'] : NULL;

  if ($op == FB_USER_OP_POST_USER) {
     // Learn some details from facebook.
    $infos = fb_users_getInfo(array($fbu), $fb);
    $info = $infos[0];

     // add stuff to $account from $info
     // here's where you add your own code, like "$account['something'] = $info['something'] "
     
     // save user data
     if (user_save($account)) {
         return TRUE;
     } else {
         return FALSE;
     }
     
  }
}

All of the above is paper programming, not code that has actually run. Unfortunately, I know nothing about how to best call user_save, given that there are account settings, profile settings, profile categories etc. If you get this code (or something like it) to work, please post the result.

Dave Cohen’s picture

I've been pretty silent on this thread because I see this as a problem best solved by custom code. Drupal has so many ways of storing data with users (the $user->data, profile module, fields, profile nodes,...) and facebook has so much different data, depending on which extended perms are granted. So I don't expect a one-size-fits-all, click to configure kind of solution to work for many people. Of course I could be wrong so I like to see snippets from anyone that has anything working.

Regarding #36... I think better to implement the FB_USER_OP_PRE_USER operation. This is invoked before the fb_user.module creates a user. That is, throw some values into the &$return parameter of hook_fb_user, and those values will be passed into user_save() when fb_user.module calls it. That hook gives you a change to change a user's name or anything else about them before the account is created.

ranx’s picture

Subscribing.

bcgarland’s picture

subscribing

jcarrig’s picture

subscribing.

escore’s picture

So I finally got around to doing something smallish with this. The following code will set the user account's language using the language set in Facebook when creating a new account. Replace "mymodule" for your own module name to make it work.

<?php
function mymodule_fb_user($op, $data, &$return) {
  $fb_app = isset($data['fb_app']) ? $data['fb_app'] : NULL;
  $fb = isset($data['fb']) ? $data['fb'] : NULL;
  $info = isset($data['info']) ? $data['info'] : NULL;

  if ($op == FB_USER_OP_PRE_USER) {
     // Set user language (wasn't able to get the FB language in a smoother way)
     fb_api_check_session($GLOBALS['_fb']);
     $fb_lang = $_SESSION['fb_locale'];
     $return['language'] = _fb_admin_i18n_map_reverse($fb_lang);
  }
}


/*
 * Mapping  Facebook locale -> Drupal language code 
 * Helper function, ripped from fb.admin.inc and slightly modified
 */
function _fb_admin_i18n_map_reverse($lang_code) {

  $languages_map = array(
    'af' => 'af_ZA',
    'ar' => 'ar_AR',
    'ay' => 'ay_BO',
    'az' => 'az_AZ',
    'be' => 'be_BY',
    'bg' => 'bg_BG',
    'bn' => 'bn_IN',
    'bs' => 'bs_BA',
    'ca' => 'ca_ES',
    'cs' => 'cs_CZ',
    'cy' => 'cy_GB',
    'da' => 'da_DK',
    'de' => 'de_DE',
    'el' => 'el_GR',
    'en' => 'en_US',
    'eo' => 'eo_EO',
    'es' => 'es_ES',
    'et' => 'et_EE',
    'eu' => 'eu_ES',
    'fa' => 'fa_IR',
    'fi' => 'fi_FI',
    'fo' => 'fo_FO',
    'fr' => 'fr_FR',
    'ga' => 'ga_IE',
    'gl' => 'gl_ES',
    'gn' => 'gn_PY',
    'gu' => 'gu_IN',
    'he' => 'he_IL',
    'hi' => 'hi_IN',
    'hr' => 'hr_HR',
    'hu' => 'hu_HU',
    'hy' => 'hy_AM',
    'id' => 'id_ID',
    'is' => 'is_IS',
    'it' => 'it_IT',
    'ja' => 'ja_JP',
    'jv' => 'jv_ID',
    'ka' => 'ka_GE',
    'kk' => 'kk_KZ',
    'km' => 'km_KH',
    'kn' => 'kn_IN',
    'ko' => 'ko_KR',
    'ku' => 'ku_TR',
    'la' => 'la_VA',
    'lt' => 'lt_LT',
    'lv' => 'lv_LV',
    'mg' => 'mg_MG',
    'mk' => 'mk_MK',
    'ml' => 'ml_IN',
    'mn' => 'mn_MN',
    'mr' => 'mr_IN',
    'ms' => 'ms_MY',
    'mt' => 'mt_MT',
    'nb' => 'nb_NO',
    'ne' => 'ne_NP',
    'nl' => 'nl_BE',
    'nn' => 'nn_NO',
    'pa' => 'pa_IN',
    'pl' => 'pl_PL',
    'ps' => 'ps_AF',
    'qu' => 'qu_PE',
    'rm' => 'rm_CH',
    'ro' => 'ro_RO',
    'ru' => 'ru_RU',
    'sa' => 'sa_IN',
    'se' => 'se_NO',
    'sk' => 'sk_SK',
    'sl' => 'sl_SI',
    'so' => 'so_SO',
    'sq' => 'sq_AL',
    'sr' => 'sr_RS',
    'sv' => 'sv_SE',
    'sw' => 'sw_KE',
    'ta' => 'ta_IN',
    'te' => 'te_IN',
    'tg' => 'tg_TJ',
    'th' => 'th_TH',
    'tl' => 'tl_ST',
    'tr' => 'tr_TR',
    'tt' => 'tt_RU',
    'uk' => 'uk_UA',
    'ur' => 'ur_PK',
    'uz' => 'uz_UZ',
    'vi' => 'vi_VN',
    'xh' => 'xh_ZA',
    'yi' => 'yi_DE',
    'zh-hans' => 'zh_CN',
    'zh-hant' => 'zh_TW',
    'zu' => 'zu_ZA',
  );
  
  $languages_map = array_flip($languages_map);
  return isset($languages_map[$lang_code]) ? $languages_map[$lang_code] : 'en';
}
?>
rumblewand’s picture

Good progress is good. Thanks for your work!

technikh’s picture

subscribingg

bjalford’s picture

Does anyone have an example of code to get content, say gender, into a field?

NickWebman’s picture

subscribing. this is huge.

kandalam’s picture

subscribing...

This seems very interesting. Harnessing the power of facebook in drupal sites.

wrathfulsquirrel’s picture

Also subscribing.

Let me ask guys. I am trying to figure out how to connect a new profile created by clicking "Connect with Facebook" button with user's FB email address (it doesn't show in the drupal "users" table). Anyone know how to do that or where to code?

kevinquillen’s picture

The RPX module is able to do this for either core user Profile or Content Profile modules.

wrathfulsquirrel’s picture

Thanks. I would check this out and leave a short information does it work accurately.

wrathfulsquirrel’s picture

It seems that Janrain Engage doesn't wrok as I wanted:
1. the bridge between Janrain Engage and Content Profile doesn't exist,
2. also there is not any "Connect with" button as I described in the Drupal for Facebook case: http://drupal.org/node/1181834.

rollingnet’s picture

Dave Cohen wrote:

I've been pretty silent on this thread because I see this as a problem best solved by custom code. Drupal has so many ways of storing data with users (the $user->data, profile module, fields, profile nodes,...) and facebook has so much different data, depending on which extended perms are granted. So I don't expect a one-size-fits-all, click to configure kind of solution to work for many people. Of course I could be wrong so I like to see snippets from anyone that has anything working.

Regarding #36... I think better to implement the FB_USER_OP_PRE_USER operation. This is invoked before the fb_user.module creates a user. That is, throw some values into the &$return parameter of hook_fb_user, and those values will be passed into user_save() when fb_user.module calls it. That hook gives you a change to change a user's name or anything else about them before the account is created.

and

I think you're better off using hook_form_alter() to pre-populate the default values.

I tried for several days to figure out in which way, during registration, save for example "birthday" or "list of friends" fields from facebook to the same standard profile fields on Drupal, but without any success.
Can you show us a working snippet for that? (I'm using 7.x-3.x version)

I think saving data from facebook's account with ease were one of the missing feature of your promising module.

Thanks in advance

Guntas’s picture

Hi all, I am looking for the patch or code which I can use to simply update the profile name and picture with facebook name and picture. I am presently using fb module.

Please help

Thanks

agileadam’s picture

Thank you RasputinJones! Some of your code helped me a lot.
In a hook_form_alter:

      if (isset($GLOBALS['_fb']) && fb_facebook_user()) {
        $fb = $GLOBALS['_fb'];
        $query = "SELECT first_name, current_location FROM user WHERE uid = me()";
        $access_token = array('auth_token' => $fb->getAccessToken);
        $result = fb_fql_query($fb, $query, $access_token);
        $form['title']['#default_value'] = $result[0]['first_name'];
        $form['field_city'][0]['#default_value']['value'] = $result[0]['current_location']['city'];
      }
skolesnyk’s picture

Guys, is there any progress on syncing Content Profile fields to Facebook user profile fields?

Dave Cohen’s picture

Component: Facebook Connect » Contrib Submodule

fb_user.module will call hook_fb_user() before calling user_save. So, your module a chance to add data that will be passed to user_save(). The profile module will honor that data, if you get the field names just right.

The example code below is for D6, and works if you've named your profile fields "profile_name_first" and "profile_name_last". In D7, it works in principle the same way, but the data structure has become wildly more complicated.

Now if someone wants to make a module that makes this stuff configurable. I.e. when editing a profile fields, add an option "grab this data from facebook". That would be cool!


function custom_fb_user($op, $data, &$return) {
  if ($op == FB_USER_OP_PRE_USER) {
    // fb_user.module is going to call user_save().  We have a chance to add data.

    // $data['info'] is data learned from facebook.
    // $return is array to be passed into user_save().

    // If the names of these profile fields change, breaks this code.
    $return['profile_name_first'] = $data['info']['first_name'];
    $return['profile_name_last'] = $data['info']['last_name'];

  }
}

Frederic wbase’s picture

For drupal 7 i can fill custom user fields like this:

function wb_connect_fb_user($op, $data, &$return) {
	global $user;
	if ($op == FB_USER_OP_PRE_USER) {
		$return['field_voornaam']['und'][0] = $data['info']['first_name'];
		$return['field_achternaam']['und'][0] =$data['info']['last_name'];
         }
  
}

Only one problem, only the first letter is saved :s

grts

frederic

kevinquillen’s picture

Aren't you missing the value item?

$return['field_fieldname']['und'][0]['value']

Frederic wbase’s picture

Of course! How Stupid of me! Thanks for your quick reply, it works like a charm now!
Maybe we should post this example in the documentation section. I think there are a lots of people searching for this one.

kevinquillen’s picture

Also... to do this you need to know what those fields are. It won't always be 'value'. For some fields, it might be URL, email, etc, some fields are different.

Frederic wbase’s picture

@kevinquillen yes i know... I have worked many times with those things... Its just that i was trying so hard to get this thing working with the fb module that i overlooked this ;-)

lazly’s picture

Subscribe! :)

Otherwise I have a problem with this solution, concrete with the hometown information. If i debug my hook with dpm() then I cant find this data tag: $data['info']['location']['name'] Its missing. :( The interesting part is that I got this permission from FB, and if I click to the profile page after login with an admin, where the module dump out the FB params, there I see it. Anybody has any idea? :) Thanks!

Dave Cohen’s picture

How do you get the data you're passing to dpm?

The piece on the user profile comes from fb_devel.module. It does not call fb_graph(), but instead:


            // Don't use fb_api() because we don't want the caching here.
            $info = $fb->api("/$fbu", array('access_token' => fb_get_token($fb)));

As you may know, not all users make that info available. You can also try facebook's graph explorer to see what's there.

lazly’s picture

Hi! Thanks the answer.
My module:

 function mymodule_fb_user($op, $data, &$return) {
  if ($op == FB_USER_OP_PRE_USER) {
    #$return['field_hometown']['und'][0]['value'] = $data['info']['location']['name'];
    $return['field_birthday']['und'][0]['value'] = date('Y-m-d', strtotime($data['info']['birthday']));
  }
  drupal_set_message('Devel: fb_user '.$op); dpm($return); dpm($data);
} 

And here I cant find the data in the $data array, but if I check the http://mysite.com/user/$uid page there I can read this:

facebook graph for /123456789:
Array
(
    [id] => 123456789
    [name] =>  --
    [first_name] => --
    [last_name] => --
    [link] =>  --
    [username] => --
    [location] => Array
        (
            [id] => 105603297474072
            [name] => Cityname
        )
    [gender] => --
    [email] => --
    [locale] => --
)

Has you got any idea about this problem? Thanks! Lazly

Dave Cohen’s picture

There's a convoluted history behind the $info passed to that hook. It used to come from a facebook api called users_getInfo(). They deprecated that, so the code switched to use something called FQL. It still uses that, but the devel info you're seeing on user/$uid comes from a new thing called the graph API.

There are a couple possible fixes for this....

a) it might be possible to add location fields to fb_users_getInfo(). You'd have to look up exactly what's available to FQL.

b) fb_users_getInfo() could be changed to use the graph query. This is a bigger change, probably not worth doing until the next major release of modules/fb.

And finally this is probably your best bet for an immediate workaround:

In your own hook, call something like:

$more_info = fb_graph($data['fbu']);

That $more_info array should end up being the same data you see on the user page.

lazly’s picture

Hi!

Unfortunately the fb_graph isnt worked for me correctly, because that want an second parameter, but I copy out the source of fb_devel_user_view function (you can find it in fb_devel module), and rewrite it. Its was successful, my module currently looks like this, and its working:

 function mymodule_fb_user($op, $data, &$return) {
  if ($op == FB_USER_OP_PRE_USER) {
    $fb = $GLOBALS['_fb'];
    try {
      $info = $fb->api('/'.$data['fbu'], array('access_token' => fb_get_token($fb)));
      $return['field_hometown']['und'][0]['value'] = $info['location']['name'];
      $return['field_birthday']['und'][0]['value'] = date('Y-m-d', strtotime($data['info']['birthday']));
      //watchdog('mymodule_fb_data',print_r($data,true));
      //watchdog('mymodule_fb_fb',print_r($fb,true));
      //watchdog('mymodule_fb_info',print_r($info,true));
    }
    catch (Exception $e) {
      watchdog('desszert_fb',
        'Failed to get info for fbu !id<br />message: !message',
        array('!id'=>$data['fbu'], '!message'=>$e->getMessage()),
        WATCHDOG_WARNING
      );
    }
  }
}

miguered’s picture

subscribing! :D