You are here

function fb_user_user in Drupal for Facebook 5.2

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

Implementation of hook_user.

File

./fb_user.module, line 393
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.

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 ($_REQUEST['fb_sig']) {

    //watchdog('debug', dprint_r($_REQUEST, 'fb_user_user request'));
    $fb_app = fb_get_app(array(
      'apikey' => $_REQUEST['fb_sig_api_key'],
    ));
    $fbu = $_REQUEST['fb_sig_user'];
  }
  else {
    if ($GLOBALS['fb']) {

      // 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);
    $fb_user_data = $fb_app_data['fb_user'];

    // our configuration
    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;
      }
      else {
        if ($op == 'login') {

          // On login, 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') {
    if (user_access('administer users') || user_access('delete own fb_user authmap') && $user->uid == $account->uid) {

      // A tab for administrators
      $items[] = array(
        'name' => 'fb_user',
        'title' => t('Facebook Applications'),
        'weight' => 1,
      );
    }
    if (user_access('edit own extended permissions') && $user->uid == $account->uid) {

      // A tab for each application the user has authorized
      $result = _fb_app_query_all();
      $apps = array();
      while ($fb_app = db_fetch_object($result)) {
        $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,
          ), array(
            'name',
            'is_app_user',
          ));
          if ($info[$fbu][0]['is_app_user']) {
            $items[] = array(
              'name' => $fb_app->label,
              'title' => $fb_app->title,
              'weight' => 2,
            );
          }
        }
      }
    }
    return $items;
  }
  else {
    if ($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
      $form['map'] = array(
        '#tree' => TRUE,
      );

      // Iterate through all facebook apps, because they do not all use the same
      // map scheme.
      $result = _fb_app_query_all();
      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,
          ), 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,
              '#default_value' => $authname,
              '#return_value' => $authname,
            );
          }
          else {
            $shared_maps[] = $fb_app->title;
            $shared_fbu = $fbu;

            // Same for all shared apps.
            $shared_module = $module;
            $shared_authname = $authname;
          }
        }
        if ($shared_maps) {
          $form['map'][$shared_module] = array(
            '#type' => 'checkbox',
            '#title' => implode('<br/>', $shared_maps),
            '#default_value' => $shared_authname,
            '#return_value' => $shared_authname,
          );
          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,
            ));
          }
        }
        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->nid] = array(
              '#type' => 'markup',
              '#value' => t('!username does not use !application.', array(
                '!username' => theme('username', $account),
                '!application' => l($fb_app->title, 'node/' . $fb_app->nid),
              )),
              '#prefix' => "\n<p>",
              '#suffix' => "</p>\n",
            );
          }
        }
      }
      return $form;
    }
    else {
      if ($op == 'form' && ($fb_app = $apps[$category])) {
        if (user_access('edit own extended permissions') && $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) {
              $form[$section] = array(
                '#type' => 'markup',
                '#value' => '<fb:add-section-button section="' . $section . '" />',
              );
            }
          }

          // http://wiki.developers.facebook.com/index.php/Extended_permissions
          $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.',
            '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',
            'sms' => 'Allow %application to send you SMS text messages.',
          );
          foreach ($permissions as $key => $t) {
            if (function_exists('fb_canvas_is_fbml') && fb_canvas_is_fbml()) {
              $form[$key] = array(
                '#type' => 'markup',
                '#value' => '<fb:prompt-permission perms="' . $key . '">' . t($t, array(
                  '%application' => $fb_app->title,
                )) . '<br /></fb:prompt-permission>',
              );
            }
            else {

              // Non-fbml page
              // TODO: use API to hide permissions we already have
              $url = url($_GET['q'], NULL, NULL, TRUE);
              $form[$key] = array(
                '#type' => 'markup',
                '#value' => l(t($t, array(
                  '%application' => $fb_app->title,
                )), "http://www.facebook.com/authorize.php", array(), "api_key={$fb_app->api_key}&v=1.0&ext_perm={$key}&next={$url}&next_cancel={$url}", NULL, TRUE, TRUE),
                '#prefix' => '<p>',
                '#suffix' => '</p>',
              );
            }
          }

          // Add buttons for boxes and info
          $sections = array(
            'profile',
            'info',
          );
          foreach ($sections as $section) {
            if (function_exists('fb_canvas_is_fbml') && fb_canvas_is_fbml()) {
              $form[$section] = array(
                '#type' => 'markup',
                '#value' => '<fb:add-section-button section="' . $section . '" />',
              );
            }

            // 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,
            )), 'http://www.facebook.com/editapps.php', array(), NULL, NULL, FALSE, TRUE),
            '#prefix' => '<p>',
            '#suffix' => "</p>\n",
          );
          return $form;
        }
      }
      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,
              ));
            }
          }
        }
        else {
          if ($op == 'delete') {
            db_query("DELETE FROM {fb_user_app} WHERE uid=%d", $account->uid);
          }
        }
      }
    }
  }
}