Index: sites/all/modules/fb/fb_user.module
===================================================================
--- sites/all/modules/fb/fb_user.module (revision 3043)
+++ sites/all/modules/fb/fb_user.module (working copy)
@@ -3,7 +3,7 @@
/**
* @file
- *
+ *
* This module allows Drupal user records to be associated with Facebook user
* ids. It can create local user accounts when Facebook users visit an
* application's canvas pages.
@@ -30,7 +30,7 @@
function _fb_user_special_page() {
// TODO: hopefully this can be simplified.
return ((arg(0) == 'user' && arg(1) == 'login') ||
- (arg(0) == 'user' && arg(1) == 'register') ||
+ (arg(0) == 'user' && arg(1) == 'register') ||
arg(0) == 'fb_user' ||
(arg(0) == 'fb' && arg(1) == 'form_cache') ||
(arg(0) == 'fb_app' && arg(1) == 'event') ||
@@ -45,11 +45,11 @@
// Keep track of all our app users. We need this info when updating
// profiles during cron. We keep session keys in case user has an
// infinite session, and we can actually log in as them during cron.
-
+
// In special cases, do not modify the uid column.
$fb_app_data = fb_app_get_data($fb_app);
$fb_user_data = $fb_app_data['fb_user']; // our configuration
-
+
if (!$user->uid || $user->uid == $fb_user_data['not_logged_in_uid'] || $user->uid == $fb_user_data['logged_in_uid']) {
// Should we even keep data for users who have not added???
$result = db_query("UPDATE {fb_user_app} SET time_access=%d, session_key='%s', session_key_expires=%d, uid=NULL WHERE apikey='%s' AND fbu=%d",
@@ -78,7 +78,7 @@
global $user;
$fb_app_data = fb_app_get_data($fb_app);
$fb_user_data = $fb_app_data['fb_user']; // our configuration
-
+
if ($op == FB_OP_INITIALIZE) {
// Here we ask facebook to prompt the user to authorize the app.
if (fb_user_authentication_is_required($fb_app)) {
@@ -92,7 +92,7 @@
$uid = $fb_app_data['fb_user']['logged_in_uid'];
}
else {
- $uid = $fb_app_data['fb_user']['not_logged_in_uid'];
+ $uid = $fb_app_data['fb_user']['not_logged_in_uid'];
}
if ($uid) {
dpm("XXX setting global user in fb_user_fb!");
@@ -105,46 +105,45 @@
// We reach this point if the user has authorized the app.
// Could be they visited a canvas page,
// or could be they clicked a fbConnect link.
-
+
$fbu = $data['fbu']; // The user id on facebook.
-
+
// Remember the original uid
$original_uid = $user->uid;
-
+
if ($user->fbu != $fbu && fb_api_check_session($fb)) {
// Try the application-specific account.
$account = user_external_load("$fbu-$fb_app->apikey@facebook.com");
if (!$account)
- // Try the cross-application account.
- $account = user_external_load("$fbu@facebook.com");
+ // Try the cross-application account.
+ $account = user_external_load("$fbu@facebook.com");
if ($account) {
- $account->fbu = $fbu;
- if ($user->uid == 0)
- $user = $account; // change the global user
- else {
- watchdog('fb_user', t('fb_user encountered something it cannot handle. The current user, !user1 is logged in. But the facebook user id %fbu is associated with another user, !user2',
- array('!user1' => theme('username', $user),
- '!user2' => theme('username', $account),
- '%fbu' => $fbu)),
- WATCHDOG_ERROR);
- }
+ $account->fbu = $fbu;
+ if ($user->uid == 0)
+ $user = $account; // change the global user
+ else if ($user->uid != $account->uid) {
+ watchdog('fb_user', t('fb_user encountered something it cannot handle. The current user, !user1 is logged in. But the facebook user id %fbu is associated with another user, !user2',
+ array('!user1' => theme('username', $user),
+ '!user2' => theme('username', $account),
+ '%fbu' => $fbu)),
+ WATCHDOG_ERROR);
+ }
}
else {
- // There is no account associated with the facebook id.
- // If the user is not anonymous, we can make an association now.
- if ($user->uid != 0 &&
- $user->uid != $fb_app_data['fb_user']['logged_in_uid']) {
- if ($fb_user_data['map_account'] == FB_USER_OPTION_MAP_ALWAYS) {
- list($module, $authname) = _fb_user_get_authmap($fb_app, $fbu);
- user_set_authmaps($user, array($module => $authname)); // is this right?
- $user->fbu = $fbu;
- //dpm("setting up authmap to associate " . theme('username', $user) . " with fbu $fbu");
- watchdog('fb_user', t('Using authmap to associate user !user with facebook user id %fbu.',
- array('!user' => theme('username', $user),
- '%fbu' => $fbu)));
- }
-
- }
+ // There is no account associated with the facebook id.
+ // If the user is not anonymous, we can make an association now.
+ if ($user->uid != 0 &&
+ $user->uid != $fb_app_data['fb_user']['logged_in_uid']) {
+ if ($fb_user_data['map_account'] == FB_USER_OPTION_MAP_ALWAYS) {
+ list($module, $authname) = _fb_user_get_authmap($fb_app, $fbu);
+ user_set_authmaps($user, array($module => $authname)); // is this right?
+ $user->fbu = $fbu;
+ //dpm("setting up authmap to associate " . theme('username', $user) . " with fbu $fbu");
+ watchdog('fb_user', t('Using authmap to associate user !user with facebook user id %fbu.',
+ array('!user' => theme('username', $user),
+ '%fbu' => $fbu)));
+ }
+ }
}
}
@@ -153,32 +152,32 @@
if (($fb_user_data['create_account'] == FB_USER_OPTION_CREATE_ADD &&
$fb->api_client->users_isAppUser()) ||
($fb_user_data['create_account'] == FB_USER_OPTION_CREATE_LOGIN)) {
-
- // We need to make a local account for this facebook user.
- $user = fb_user_create_local_user($fb, $fb_app, fb_facebook_user($fb),
- array('app_specific' => $fb_user_data['unique_account'],
- 'roles' => array($fb_user_data['new_user_rid'] => TRUE),
+
+ // We need to make a local account for this facebook user.
+ $user = fb_user_create_local_user($fb, $fb_app, fb_facebook_user($fb),
+ 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)));
-
+ watchdog('fb_user', t("Created new user !username for application %app",
+ array('!username' => theme('username', $user),
+ '%app' => $fb_app->label)));
+
}
}
-
+
// It's possible the user was already created by another app.
// In this case we need to add our role.
if ($user->fbu == fb_facebook_user() &&
- $fb_user_data['new_user_rid'] && !$user->roles[$fb_user_data['new_user_rid']]) {
+ $fb_user_data['new_user_rid'] && !$user->roles[$fb_user_data['new_user_rid']]) {
// there should be an API for this...
- db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)',
- $user->uid, $fb_user_data['new_user_rid']);
+ db_query('INSERT INTO {users_roles} (uid, rid) VALUES (%d, %d)',
+ $user->uid, $fb_user_data['new_user_rid']);
watchdog('fb_user', t("Added role %role to existing user !username for application %app",
- array('!username' => theme('username', $user),
- '%app' => $fb_app->label,
- '%role' => $fb_user_data['new_user_rid'])));
+ array('!username' => theme('username', $user),
+ '%app' => $fb_app->label,
+ '%role' => $fb_user_data['new_user_rid'])));
}
-
+
if ($user->uid != $original_uid &&
!(arg(0) == 'fb_app' && arg(1) == 'event')) {
// We've changed the user. In order to ensure that drupal handles
@@ -186,27 +185,27 @@
// again. Skip this for the profile tab, as facebook does not allow
// redirects (or persistent session) there.
if (function_exists('fb_canvas_is_fbml') &&
- (fb_canvas_is_fbml() || fb_canvas_is_iframe()) &&
- (!$_REQUEST['fb_sig_in_profile_tab'])) {
-
- // Redirect to a canvas page
- $url = fb_canvas_fix_url(url(fb_scrub_urls($_REQUEST['q']), NULL, NULL, TRUE), $fb_app);
- if (fb_verbose())
- watchdog('fb_debug', "User uid is now {$user->uid} (was {$original_uid}), redirecting to $url to ensure permissions are correct."); // debug
- $fb->redirect($url);
+ (fb_canvas_is_fbml() || fb_canvas_is_iframe()) &&
+ (!$_REQUEST['fb_sig_in_profile_tab'])) {
+
+ // Redirect to a canvas page
+ $url = fb_canvas_fix_url(url(fb_scrub_urls($_REQUEST['q']), NULL, NULL, TRUE), $fb_app);
+ if (fb_verbose())
+ watchdog('fb_debug', "User uid is now {$user->uid} (was {$original_uid}), redirecting to $url to ensure permissions are correct."); // debug
+ $fb->redirect($url);
}
else if (!fb_settings(FB_SETTINGS_APP_NID)) {
// Facebook connect pages (not callback or receiver)
$path = $_REQUEST['q'];
- if (fb_verbose())
- watchdog('fb_debug', "User uid is now {$user->uid} (was {$original_uid}), redirecting to $path to ensure permissions are correct."); // debug
+ if (fb_verbose())
+ watchdog('fb_debug', "User uid is now {$user->uid} (was {$original_uid}), redirecting to $path to ensure permissions are correct."); // debug
drupal_goto($path);
}
}
-
+
// Keep a record of when user accesses app.
_fb_user_track($fb, $fb_app, $user);
-
+
// We don't want user's who are not logged in (in the facebook sense) to
// login locally. So let's make sure they've added the app before doing
// anything related to Drupal accounts.
@@ -222,7 +221,7 @@
}
*/
// Now do I need a goto or some such???
-
+
// debug
/*
drupal_set_message("To Drupal, you are " . theme('username', $user));
@@ -252,7 +251,7 @@
$event_type = $data['event_type'];
// Ensure fb_user_app table accurately reflects whether user has authorized.
-
+
if ($event_type == FB_APP_EVENT_POST_AUTHORIZE) {
// User has authorized us to know some details about her.
db_query("REPLACE INTO {fb_user_app} (apikey, fbu, added, session_key, session_key_expires) VALUES ('%s', %d, 1, '%s', %d)",
@@ -281,7 +280,7 @@
function fb_user_authentication_is_required($fb_app) {
$fb_app_data = fb_app_get_data($fb_app);
$fb_user_data = $fb_app_data['fb_user']; // our configuration
-
+
if ($fb_user_data['require_login'] == FB_USER_OPTION_REQUIRE_LOGIN) {
// The application is configured to require login on all canvas pages.
// However, there are exceptions.
@@ -290,7 +289,7 @@
return FALSE;
}
// There may be other exceptions, for example some ajax callbacks. Potential todo item.
-
+
// No exceptions apply, authentication is required.
return TRUE;
}
@@ -298,34 +297,34 @@
function fb_user_form_alter($form_id, &$form) {
//drupal_set_message("fb_user_form_alter($form_id) " . dpr($form, 1));
-
+
// Add our settings to the fb_app edit form.
if (is_array($form['fb_app_data'])) {
$node = $form['#node'];
$fb_app_data = fb_app_get_data($node->fb_app);
$fb_user_data = $fb_app_data['fb_user'];
-
+
$form['fb_app_data']['fb_user'] = array('#type' => 'fieldset',
'#title' => t('Facebook user settings'),
'#tree' => TRUE,
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
-
- $form['fb_app_data']['fb_user']['require_login'] =
+
+ $form['fb_app_data']['fb_user']['require_login'] =
array('#type' => 'radios',
'#title' => t('Require Login'),
'#description' => t('If some of your canvas pages are visible to the public at large, allow anyone. You will have to call Facebook\'s require_login() on pages that require more information about the user.
Allow only logged-in users if you want Drupal for Facebook to call require_login() on every page.'),
- '#options' =>
+ '#options' =>
array(FB_USER_OPTION_ALLOW_ANON => t('Allow anyone'),
FB_USER_OPTION_REQUIRE_LOGIN => t('Allow logged-in users'),
),
'#default_value' => isset($fb_user_data['require_login']) ? $fb_user_data['require_login'] : FB_USER_OPTION_ALLOW_ANON,
'#required' => TRUE,
);
-
-
- $form['fb_app_data']['fb_user']['create_account'] =
+
+
+ $form['fb_app_data']['fb_user']['create_account'] =
array('#type' => 'radios',
'#title' => t('Create Local Account'),
'#description' => t('This option will create a local account automatically and create an entry in the authmap table. This happens whenever the user visits a canvas page, except pages whose path starts with "user/" and the landing page for anonymous users. Choose never to use Drupal\'s built in user registration.'),
@@ -346,15 +345,15 @@
'#default_value' => isset($fb_user_data['map_account']) ? $fb_user_data['map_account'] : FB_USER_OPTION_MAP_ALWAYS,
'#required' => TRUE,
);
-
+
$form['fb_app_data']['fb_user']['unique_account'] =
array('#type' => 'checkbox',
'#title' => t('Make Account Mapping Unique (experimental, not recommended)'),
'#description' => t('If checked, the relationship between the local uid and the Facebook id applies only to this Application. This matters only when you host more than one application on this instance of Drupal.'),
'#default_value' => $fb_user_data['unique_account'],
);
-
-
+
+
// TODO: prompt for role with a select. Don't make user figure out id
$form['fb_app_data']['fb_user']['new_user_rid'] =
array('#type' => 'select',
@@ -363,7 +362,7 @@
'#description' => t('When the local uid is known and the user has logged in (in the Facebook sense) to the app, the user will be granted this role.'),
'#default_value' => $fb_user_data['new_user_rid'],
);
-
+
// Experimental. May be removed or drastically changed anytime
// TODO: fix this so that it prompts for username with autocomplete, not a uid.
$form['fb_app_data']['fb_user']['not_logged_in_uid'] =
@@ -378,8 +377,8 @@
'#description' => t('If allowing logged in users, when such a user visits the site, and they do not have a local Drupal account, which Drupal user should they be treated as? Use 0 for the Anonymous user (recommended - this feature is experimental and likely to disappear), or create a dedicated account for this purpose.'),
'#default_value' => $fb_user_data['logged_in_uid'],
);
-
-
+
+
}
else if ($form_id == 'user_edit' && ($app = $form['#fb_app'])) {
// Disable buttons on user/edit/app pages, nothing to submit
@@ -406,7 +405,7 @@
// Post from iframe
$fbu = fb_facebook_user();
}
-
+
if ($fb_app && $op == 'insert' || $op == 'login') {
// A facebook user has logged in. We can map the two acounts together.
$fb_app_data = fb_app_get_data($fb_app);
@@ -414,7 +413,7 @@
if ($fbu &&
$fb_user_data['map_account'] == FB_USER_OPTION_MAP_ALWAYS) {
list($module, $authname) = _fb_user_get_authmap($fb_app, $fbu);
-
+
if ($op == 'insert') {
// User has registered, we set up the authmap this way...
$edit['authname_fb_user'] = $authname;
@@ -427,7 +426,7 @@
// TODO: if the app has a role, make sure the user gets that role. (presently, that will not happen until their next request)
}
}
-
+
// Add tabs on user edit pages to manage maps between local accounts and facebook accounts.
if ($op == 'categories') {
if (user_access('administer users') ||
@@ -447,18 +446,18 @@
$apps[$fb_app->label] = $fb_app;
$fb_app_data = fb_app_get_data($fb_app);
$fb_user_data = $fb_app_data['fb_user']; // our configuration
-
+
$fbu = _fb_user_get_fbu($account->uid, $fb_app);
-
+
if ($fbu && !$info[$fbu]) {
// The drupal user is a facebook user. Now, learn more from facebook.
$fb = fb_api_init($fb_app, FB_FBU_ANY);
// Note: this requires infinite session with facebook. TODO: fallback to fb_user_app table.
- $info[$fbu] = $fb->api_client->users_getInfo(array($fbu),
+ $info[$fbu] = $fb->api_client->users_getInfo(array($fbu),
array('name',
'is_app_user',
));
-
+
if ($info[$fbu][0]['is_app_user']) {
$items[] = array('name' => $fb_app->label,
'title' => $fb_app->title,
@@ -473,7 +472,7 @@
if (!user_access('administer users') &&
!(user_access('delete own fb_user authmap') && $user->uid == $account->uid))
return; // hide from this user
-
+
$form['map'] = array('#tree' => TRUE);
// Iterate through all facebook apps, because they do not all use the same
// map scheme.
@@ -481,25 +480,25 @@
while ($fb_app = db_fetch_object($result)) {
$fb_app_data = fb_app_get_data($fb_app);
$fb_user_data = $fb_app_data['fb_user']; // our configuration
-
+
$fbu = _fb_user_get_fbu($account->uid, $fb_app);
if ($fbu && !$info[$fbu]) {
// The drupal user is a facebook user. Now, learn more from facebook.
$fb = fb_api_init($fb_app, FB_FBU_ANY);
// Note: this requires infinite session with facebook or active fbconnect session. TODO: fallback to fb_user_app table.
- $info[$fbu] = $fb->api_client->users_getInfo(array($fbu),
+ $info[$fbu] = $fb->api_client->users_getInfo(array($fbu),
array('name',
'is_app_user',
));
//dpm($info[$fbu], "Info from facebook for $fbu");
-
-
+
+
}
-
+
if ($fbu) {
list($module, $authname) = _fb_user_get_authmap($fb_app, $fbu);
-
+
if ($fb_user_data['unique_account']) {
$form['map'][$module] = array('#type' => 'checkbox',
'#title' => $fb_app->title,
@@ -523,7 +522,7 @@
if ($info[$shared_fbu]) {
$data = $info[$shared_fbu][0];
$fb_link = l($data['name'], 'http://www.facebook.com/profile.php', NULL, 'id='.$data['uid']);
-
+
$form['map'][$shared_module]['#description'] .= t('Local account (!username) corresponds to !profile_page on Facebook.com.',
array('!username' => theme('username', $account),
'!profile_page' => $fb_link));
@@ -553,7 +552,7 @@
$GLOBALS['user']->uid == $account->uid) {
// Application-specific settings
$form['#fb_app'] = $fb_app; // used in hook_form_alter.
-
+
if (function_exists('fb_canvas_is_fbml') && fb_canvas_is_fbml()) {
$sections = array('profile', 'info');
foreach ($sections as $section) {
@@ -564,11 +563,11 @@
}
}
// http://wiki.developers.facebook.com/index.php/Extended_permissions
- $permissions =
- array('email' => 'Allow %application to send you email',
+ $permissions =
+ array('email' => 'Allow %application to send you email',
'offline_access' => 'Grant %application access to your Facebook profile.',
- 'status_update' => 'Allow %application to set your status.',
- 'photo_upload' => 'Allow %application to upload photos.',
+ 'status_update' => 'Allow %application to set your status.',
+ 'photo_upload' => 'Allow %application to upload photos.',
'create_listing' => 'Allow %application to create marketplace listings on your behalf.',
'create_event' => 'Allow %application to create events on your behalf.',
'rsvp_event' => 'Allow %application to RSVP to events on your behalf',
@@ -582,7 +581,7 @@
t($t, array('%application' => $fb_app->title)) .
'
',
);
- }
+ }
else {
// Non-fbml page
// TODO: use API to hide permissions we already have
@@ -597,10 +596,10 @@
'#prefix' => '
', '#suffix' => '
', ); - + } } - + // Add buttons for boxes and info $sections = array('profile', 'info'); foreach ($sections as $section) { @@ -612,7 +611,7 @@ } // No way to add these to a non-canvas page at the moment } - + $form['description'] = array('#type' => 'markup', '#value' => l(t('All settings for %application (and other Facebook Applications).', array('%application' => $fb_app->title)), @@ -626,7 +625,7 @@ } else if ($op == 'update' && $category == 'fb_user') { //dpm($edit, "fb_user_user($op)"); - + if (is_array($edit['map'])) foreach ($edit['map'] as $module => $authname) { user_set_authmaps($account, array($module => $authname)); @@ -641,11 +640,11 @@ /** * Helper function to create an authname for the authmap table. - * + * * When a single Drupal instance hosts multiple Facebook apps, the apps can * share the same mapping, or each have their own. - * - * @return an array with both a 'module' and an authname. A + * + * @return an array with both a 'module' and an authname. A * data structure necessary for Drupal's authmap api. */ function _fb_user_get_authmap($fb_app, $fbu) { @@ -662,17 +661,17 @@ $authname = "$fbu@facebook.com"; $module = "fb_user"; } - + //return array('module' => $module, 'authname' => $authname); return array($module, $authname); } /** * 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. @@ -682,27 +681,27 @@ $config = array()) { // 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)"); - + list($module, $authname) = _fb_user_get_authmap($fb_app, $fbu); - + $account = user_external_load($authname); - + if (!$account) { // Create a new user in our system - + // Default username is authname, usernames must be unique. $config['username'] = $authname; - + // Allow third-party module to adjust any of our settings before we create // the user. $config = fb_invoke(FB_OP_PRE_USER, array('fbu' => $fbu, - 'fb' => $GLOBALS['fb'], - 'fb_app' => $fb_app), - $config); - + 'fb' => $GLOBALS['fb'], + 'fb_app' => $fb_app), + $config); + // TODO: double-check that username is not taken. $user_default = array('name' => $config['username'], 'pass' => user_password(), @@ -710,7 +709,7 @@ 'status' => 1, 'authname_fb_user' => $authname, ); - + // Allow $config to set other values, including mail $user_default = array_merge($user_default, $config); @@ -720,7 +719,7 @@ if ($rid) $user_default['roles'][$rid] = $value; $user_default['fbu'] = $fbu; // Will get saved as user data. - + $account = user_save('', $user_default); watchdog('fb_user', t('New user: %name %email.', array('%name' => theme('username', $account), '%email' => '<'. $account->mail .'>')), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit')); @@ -728,33 +727,33 @@ // Allow third-party modules to act after account creation. //$config = fb_invoke($fb_app, FB_OP_POST_USER, NULL, array('account' => $account)); fb_invoke(FB_OP_POST_USER, array('account' => $account, - 'fb_app' => $fb_app, - 'fb' => $fb)); + 'fb_app' => $fb_app, + 'fb' => $fb)); // TODO: move this to fb_action. Temporarily disabled. if (FALSE) { // Prepare to send an email. $base = url('