Index: fb_user.module =================================================================== --- fb_user.module (revision 655) +++ fb_user.module (working copy) @@ -49,9 +49,10 @@ // Check if the local account is already made. if ($user->fbu != fb_facebook_user()) { // We need to make a local account for this facebook user. - $user = fb_user_create_local_user(fb_facebook_user(), - $fb_user_data['unique_account'], - array($fb_user_data['new_user_rid'] => TRUE)); + $user = fb_user_create_local_user($fb_app, fb_facebook_user(), + array('app_specific' => $fb_user_data['unique_account'], + 'roles' => array($fb_user_data['new_user_rid'] => TRUE), + )); watchdog('fb_user', t("Created new user !username for application %app", array('!username' => theme('username', $user), '%app' => $fb_app->label))); @@ -213,23 +214,27 @@ } } +/** + * Creates a local Drupal account for the specified facebook user id. + * + * @param fbu + * The facebook user id corresponding to this account. + * + * @param config + * An associative array with user configuration. Possible values include: + * 'app_specific' - Set to true if the same facebook id might correspond to different local accounts, depending on which apps the user has used. Set to false if the user shares one local account across facebook apps. + * 'roles' - an array with keys corresponding to role ids the new user should receive. + */ +function fb_user_create_local_user($fb_app, $fbu, + $config = array()) { -function fb_user_create_local_user($fbu = NULL, $app_specific = FALSE, $roles = array()) { - global $fb; - - if (!$fbu) - $fbu = fb_facebook_user(); - if (!$fbu) - return; // User not logged into facebook, can't create local account - - $info = $fb->api_client->users_getInfo($fbu, array('first_name', 'last_name')); - $username = $info[0]['first_name'] .' '. $info[0]['last_name']; + // TODO: ensure $fbu is a real user, not FB_FB_ANY or FB_FBU_CURRENT // debugging. //drupal_set_message("Facebook knows you as $username ($fbu)"); // map fbu to uid, include apikey if user is app_specific - if ($app_specific) + if ($config['app_specific']) // would rather use the shorter app id (not apikey), but no way to query it $authmap = "$fbu-$fb_app->apikey@facebook.com"; else @@ -239,28 +244,46 @@ if (!$account) { // Create a new user in our system - // TODO: handle case when username is already taken. - $user_default = array('name' => $username, + + // We need a username that will not collide with any already in our + // system. Could use $authmap, but this will be just slightly more + // user-friendly. + if ($config['app_specific'] && !$config['username']) + $config['username'] = "$fbu-$fb_app->label@facebook"; + else + $config['username'] = "$fbu@facebook"; + + // Allow third-party module to adjust any of our settings before we create + // the user. + $config = _fb_invoke($fb_app, FB_OP_PRE_USER, + $config, array('fbu' => $fbu)); + + // TODO: double-check that username is not taken. + $user_default = array('name' => $config['username'], 'pass' => user_password(), - 'init' => db_escape_string($username), + 'init' => db_escape_string($config['username']), 'status' => 1, 'authname_fb_user' => $authmap, ); + $user_default['roles'][DRUPAL_AUTHENTICATED_RID] = 'authenticated user'; - foreach ($roles as $rid => $value) - if ($rid) - $user_default['roles'][$rid] = $value; + if (count($config['roles'])) + foreach ($config['roles'] as $rid => $value) + if ($rid) + $user_default['roles'][$rid] = $value; $user_default['fbu'] = $fbu; // Will get saved as user data. + + $account = user_save('', $user_default); - $account = user_save('', $user_default); + // Is there a need for POST_USER hook_fb call? Or is hook_user sufficient? } - + if (!$account->fbu) { // This should only happen on older, automatically created accounts. $account->fbu = $fbu; user_save($account, array('fbu' => $fbu)); } - + return $account; } Index: fb.module =================================================================== --- fb.module (revision 655) +++ fb.module (working copy) @@ -7,6 +7,7 @@ define('FB_OP_GET_FBU', 'get_fbu'); // Query the local user's FB account define('FB_OP_GET_APP', 'get_app'); // Query which app a FB callback addresses define('FB_OP_GET_INFINITE_SESSION', 'get_inf_sess'); // Query infinite session data +define('FB_OP_PRE_USER', 'pre_user'); // Before account creation, fb_user.module define('FB_GRANT_REALM_FRIEND', 'fb_friend'); define('FB_GRANT_REALM_GROUP', 'fb_group');