You are here

function fb_user_user in Drupal for Facebook 6.2

Same name and namespace in other branches
  1. 5.2 fb_user.module \fb_user_user()
  2. 5 fb_user.module \fb_user_user()
  3. 6.3 fb_user.module \fb_user_user()

Implementation of hook_user.

File

./fb_user.module, line 470
This module manages relations between local Drupal user accounts and their accounts on facebook.com.

Code

function fb_user_user($op, &$edit, &$account, $category = NULL) {
  global $user;
  static $apps;

  // If form posted from an FBML canvas page, we learn the app and fbu from the post.
  // TODO: do we need additional validation here? (i.e. an fb_api_init to confirm the facebook params?)
  if (!empty($_REQUEST['fb_sig'])) {

    //watchdog('debug', print_r($_REQUEST, 'fb_user_user request'));
    $fb_app = fb_get_app(array(
      'apikey' => $_REQUEST['fb_sig_api_key'],
    ));
    $fbu = isset($_REQUEST['fb_sig_user']) ? $_REQUEST['fb_sig_user'] : NULL;
  }
  elseif (!empty($GLOBALS['_fb'])) {

    // Post from iframe, or facebook connect page, or canvas page.
    $fbu = fb_facebook_user();
    $fb_app = $GLOBALS['_fb_app'];
  }
  if (!empty($fb_app) && $op == 'load' && $account->uid) {
    if (!$account->mail) {

      // Use proxied email, if facebook app is active and user uses it.
      // TODO: confirm drupal never saves proxied address to users.mail.
      $account->mail = fb_user_get_proxied_email($fbu, $fb_app);
      $account->fb_user_proxied_mail = $account->mail;

      // Remember where we got address.
    }
  }
  if (!empty($fb_app) && $op == 'insert' || $op == 'login') {

    // A facebook user has logged in.  We can map the two accounts together.
    $fb_user_data = _fb_user_get_config($fb_app);
    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') {

        // New user, we set up the authmap this way...
        $edit['authname_fb_user'] = $authname;
      }
      elseif ($op == 'login') {

        // Existing user, we set up the map this way...
        user_set_authmaps($account, array(
          $module => $authname,
        ));
      }

      // 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') {

    // A tab allowing authmaps to be changed.
    $items[] = array(
      'name' => 'fb_user',
      'title' => t('Facebook Applications'),
      'access callback' => 'fb_user_access_own',
      'access arguments' => array(
        1,
        'delete own fb_user authmap',
        TRUE,
      ),
      'weight' => 1,
    );
    return $items;
  }
  elseif ($op == 'form' && $category == 'fb_user') {
    if (!user_access('administer users') && !(user_access('delete own fb_user authmap') && $user->uid == $account->uid)) {
      return;
    }

    // hide from this user
    // Iterate through all facebook apps, because they do not
    // necessarily use the same map scheme.
    $apps = fb_get_all_apps();
    foreach ($apps as $fb_app) {
      $fb_user_data = _fb_user_get_config($fb_app);
      $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,
        ), array(
          'name',
          'is_app_user',
        ));
      }
      if ($fbu) {
        list($module, $authname) = _fb_user_get_authmap($fb_app, $fbu);
        $shared_maps[] = $fb_app->label;
        $shared_fbu = $fbu;

        // Same for all shared apps.
        $shared_module = $module;
        $shared_authname = $authname;
      }
      if ($shared_maps) {

        // One authmap entry applies to more than on app.
        $form['map'][$shared_module] = array(
          '#type' => 'checkbox',
          '#title' => implode(', ', $shared_maps),
          '#default_value' => $shared_authname,
          '#return_value' => $shared_authname,
        );
        if ($info[$shared_fbu]) {
          $data = $info[$shared_fbu][0];
          $fb_link = l($data['name'] ? $data['name'] : $fbu, 'http://www.facebook.com/profile.php', array(
            'query' => array(
              'id' => $data['uid'],
            ),
          ));
          $form['map'][$shared_module]['#description'] .= t('Local account !username corresponds to !profile_page on Facebook.com.', array(
            '!username' => l($account->name, 'user/' . $account->uid),
            '!profile_page' => $fb_link,
          ));
        }
      }
      if (!$fbu) {
        if ($user->uid == $account->uid) {

          // TODO: give a user a way to map their facebook account to their local account.
        }
        else {
          $form[$fb_app->label] = array(
            '#type' => 'markup',
            '#value' => t('!username does not use !application.', array(
              '!username' => theme('username', $account),
              '!application' => $fb_app->label,
            )),
            '#prefix' => "\n<p>",
            '#suffix' => "</p>\n",
          );
        }
      }
    }
    if (isset($form)) {
      $form['map']['#tree'] = TRUE;
    }
    else {

      // Could add a facebook connect button or canvas page authorization link.
      $form['description'] = array(
        '#type' => 'markup',
        '#value' => t('This account is not associated with a Facebook Application.'),
        '#prefix' => '<p>',
        '#suffix' => '</p>',
      );
    }
    return $form;
  }
  elseif ($op == 'update' && $category == 'fb_user') {
    if (is_array($edit['map'])) {
      foreach ($edit['map'] as $module => $authname) {
        user_set_authmaps($account, array(
          $module => $authname,
        ));
      }
    }
  }
  elseif ($op == 'delete') {
    db_query("DELETE FROM {fb_user_app} WHERE uid=%d", $account->uid);
  }
}