Skip to content
fb_devel.module 24.8 KiB
Newer Older
// $Id$
/**
 * @file
 * Makes development with Drupal for Facebook much easier.  Keep this
 * module enabled until you're confident your app works perfectly.
Dave Cohen's avatar
Dave Cohen committed
 *
 * Produces warning messages and log messages
 * when it detects something is wrong with
 * your configuration.
Dave Cohen's avatar
Dave Cohen committed
 *
 * Runs tests for Drupal's status page.
Dave Cohen's avatar
Dave Cohen committed
 *
function fb_devel_menu() {
  $items['fb/devel'] = array(
    'page callback' => 'fb_devel_page',
    'type' => MENU_CALLBACK,
    'access callback' => TRUE, /* TODO: restrict access */
  );
Dave Cohen's avatar
Dave Cohen committed

  $items['fb/devel/fbu'] = array(
    'page callback' => 'fb_devel_fbu_page',
    'type' => MENU_CALLBACK,
  $items['fb/devel/tab'] = array(
    'page callback' => 'fb_devel_tab',
    'type' => MENU_CALLBACK,
Dave Cohen's avatar
Dave Cohen committed
    'access callback' => TRUE, /* TODO: restrict access */
Dave Cohen's avatar
Dave Cohen committed

  // Return some info for debugging AHAH problems
  $items['fb/devel/js'] = array(
    'page callback' => 'fb_devel_js',
    'type' => MENU_CALLBACK,
    'access callback' => TRUE,
  );

  // fb_settings.inc sanity check.
  if (isset($GLOBALS['fb_init_no_settings'])) {
    if (user_access('access administration pages') && module_exists('fb_canvas')) {
      drupal_set_message(t('!drupal_for_facebook has been enabled, but fb_settings.inc is not included in settings.php.  Please read the !readme.',
                           array('!drupal_for_facebook' => l(t('Drupal for Facebook'), 'http://drupal.org/project/fb'),
                                 // This link should work with clean URLs
                                 // disabled.
                                 '!readme' => '<a href='. base_path() . drupal_get_path('module', 'fb') .'/README.txt>README.txt</a>')), 'error');
    }
  }


Dave Cohen's avatar
Dave Cohen committed

  if ($apikey = variable_get(FB_VAR_APIKEY, NULL)) {
    if ($label = variable_get(FB_CONNECT_VAR_PRIMARY, NULL)) {
      $fb_app = fb_get_app(array('label' => $label));
      if ($fb_app && ($fb_app->apikey != $apikey)) {
        $message = t('Drupal for Facebook has detected a problem.  \'fb_apikey\' (%fb_apikey) is not the same as the primary application %label (%fb_primary_apikey).',
                     array(
                       '%fb_apikey' => $apikey,
                       '%fb_primary_apikey' => $fb_app->apikey,
                       '%label' => $fb_app->label,
                     ));
        if (user_access(FB_PERM_ADMINISTER)) {
          drupal_set_message($message, 'error');
        }
        watchdog('fb_devel', $message, array(), WATCHDOG_WARNING);
      }
  if (module_exists('fb_user')) {
    if (db_result(db_query("SELECT count(*) FROM {authmap} WHERE module='fb_user'"))) {
      $message = 'fb_user data has not been migrated from authmap table.  Run update.php.';
      $args = array();
      if (user_access('access administration pages')) {
        drupal_set_message(t($message, $args), 'error');
      }
      watchdog('fb_devel', $message, $args, WATCHDOG_ERROR);
Dave Cohen's avatar
Dave Cohen committed
/**
 * Implements hook_fb().
 */
function fb_devel_fb($op, $data, &$return) {
  $fb_app = isset($data['fb_app']) ? $data['fb_app'] : NULL;
  $fb = isset($data['fb']) ? $data['fb'] : NULL;
Dave Cohen's avatar
Dave Cohen committed

    if (fb_settings(FB_SETTINGS_APIKEY) &&
        ($fb_app->apikey != fb_settings(FB_SETTINGS_APIKEY))) {
      $message = t('Drupal for Facebook has detected a problem.  The initialized app has an apikey (%fb_app_apikey), while the settings indicates a different apikey (%fb_settings_apikey).', array(
                     '%fb_app_apikey' => $fb_app->apikey,
                     '%fb_settings_apikey' => fb_settings(FB_SETTINGS_APIKEY),
                   ));
      drupal_set_message($message, 'error');
      watchdog('fb_devel', $message, array(), WATCHDOG_WARNING);
Dave Cohen's avatar
Dave Cohen committed
      $errors++;
    // This value comes from url rewriting.  Recommended on canvas pages.
    $apikey = fb_settings(FB_SETTINGS_CB);
    if ($apikey && $apikey != $fb_app->apikey) {
      $message = t('fb_app id (%fb_app_id) does not equal fb settings id (%fb_settings_id).  This is usually caused by the wrong callback url on your <a href="!url">facebook application settings form</a>.',
                   array('%fb_app_id' => $fb_app->apikey,
                         '%fb_settings_id' => $apikey,
                         '!url' => "http://www.facebook.com/developers/apps.php",
                   ));
      drupal_set_message($message, 'warning');
      watchdog('fb_devel', $message, array(), WATCHDOG_WARNING);
      $errors++;
    // Theme sanity check.  Earlier errors cause this to fail.
    global $theme; // for debug message
    if (!$errors && isset($theme) && !variable_get('site_offline', FALSE)) {
      $message = t('Drupal for Facebook is unable to override the theme settings.  This is usually because some module causes theme_init() to be invoked before fb_init().',
                 array(
                   '!drupal_for_facebook' => l(t('Drupal for Facebook'), 'http://drupal.org/project/fb'),
                   // This link should work with clean URLs
                   // disabled.
                   '!readme' => '<a href='. base_path() . '/' . drupal_get_path('module', 'fb') . '/README.txt>README.txt</a>'));
      drupal_set_message($message, 'error');
      watchdog('fb_devel', $message, array(), WATCHDOG_WARNING);
Dave Cohen's avatar
Dave Cohen committed

    // Catch badly formed links ASAP.
    if ($apikey && !fb_is_canvas() && !fb_is_tab()) {
Dave Cohen's avatar
Dave Cohen committed
      // Skip check on callbacks from facebook.
      if ((arg(0) != 'fb_app') || (arg(1) != 'event')) {
        $message = t('URL starts with %prefix.  This should never happen on connect pages.  Did the previous page have a badly formed link?', array(
                     '%prefix' => FB_SETTINGS_CB . '/' . $apikey,
Dave Cohen's avatar
Dave Cohen committed
                   ));
        drupal_set_message($message, 'error');
        $errors++;
      }
    }
    // path replacement sanity check
    global $base_path;
    if ($base_path == "/{$fb_app->canvas}/") {
      $message = t('Facebook canvas page matches Drupal base_path (%base_path).  This is currently not supported.',
                   array('%base_path' => $base_path));
      drupal_set_message($message, 'error');
      watchdog('fb_devel', $message);
Dave Cohen's avatar
Dave Cohen committed
    // Old API Sanity check.
    if (isset($_REQUEST['fb_sig'])) {
      $message = t('Passed old-style fb_sig parameters.  Go to !url, edit your application.  Under "migrations" enable "new sdks".', array(
                     '!url' => 'http://www.facebook.com/developers/apps.php',
                   ));
      dpm($message);
      watchdog('fb_devel', $message);
    }
    // server URL sanity check
    // This is an expensive test, because it invokes api_client.
Dave Cohen's avatar
Dave Cohen committed
    try {
      $props = $fb->api(array(
Dave Cohen's avatar
Dave Cohen committed
                 'method' => 'admin.getAppProperties',
                 'access_token' => fb_get_token($fb),
Dave Cohen's avatar
Dave Cohen committed
                 'properties' => array('connect_url', 'callback_url'),
               ));
      $props = json_decode($props, TRUE);
Dave Cohen's avatar
Dave Cohen committed
      if (is_array($props)) {
        foreach ($props as $prop => $url) {
          if ($url && (strpos($url, $GLOBALS['base_url']) === FALSE)) {
            $message = t('The Facebook Application labeled %label has a suspicious %prop.  The value is %value, while something starting with %url was expected.  Consider editing !applink.', array(
Dave Cohen's avatar
Dave Cohen committed
                         '%label' => $fb_app->label,
                         '%prop' => $prop,
                         '%value' => $url,
                         '%url' => $GLOBALS['base_url'],
                         '!applink' => l($fb_app->label, FB_PATH_ADMIN_APPS . '/' . $fb_app->label),
                       ));
Dave Cohen's avatar
Dave Cohen committed
            if (user_access('access administration pages')) {
              drupal_set_message($message, 'error');
            }
Dave Cohen's avatar
Dave Cohen committed
            watchdog('fb_devel', $message);
Dave Cohen's avatar
Dave Cohen committed
    }
    catch (Exception $e) {
      dpm($e, __FUNCTION__);
Dave Cohen's avatar
Dave Cohen committed
      if ($e->getCode() == 102) {
        // Session key invalid or no longer valid 102, which we can ignore.
      }
      else {
        fb_log_exception($e, t('Failed to get app properties for %name.', array('%name' => $fb_app->title)));
      }
    // Account mapping format has changed!
    if (isset($fb_app_data['fb_user']) && !is_array($fb_app_data['fb_user']['map_account'])) {
      $message = 'The options for mapping facebook account to local accounts has changed.  You must manually <a href=!url>edit your application</a>.  Look for the map accounts options under facebook user settings.';
      $args = array('!url' => url(FB_PATH_ADMIN_APPS . '/' . $fb_app->label));
      if (user_access('access administration pages')) {
        drupal_set_message(t($message, $args), 'error');
      }
      watchdog('fb_devel', $message, $args, WATCHDOG_ERROR);
  elseif ($op == FB_APP_OP_EVENT) {
    $type = $data['event_type'];
    // Facebook has notified us of some event.
    $message = t('Facebook has notified the %label application of a %type event.',
                 array('%label' => $fb_app->label,
                       '%type' => $type));
    $message .= dprint_r($data, 1);
    $message .= dprint_r($_REQUEST, 1);
    watchdog('fb_devel', $message);
  }

  elseif ($op == FB_OP_JS) {
    // Start debugger
    //$return[] = "debugger; // added by fb_devel.module";
  }
Dave Cohen's avatar
Dave Cohen committed
  elseif ($op == FB_OP_POST_INIT) {
    if (isset($_SESSION['fb_devel'])) {
      // Counter helps track how long session has been around.
      $_SESSION['fb_devel']['FB_OP_POST_INIT'] = $_SESSION['fb_devel']['FB_OP_POST_INIT'] + 1;
    }
    else {
      $_SESSION['fb_devel']['FB_OP_POST_INIT'] = 1;
    }
    // Javascript to help us with sanity checks.
    drupal_add_js(array(
                    'fb_devel' => array(
                      'session_id' => session_id(),
                      'session_name' => session_name(),
                    ),
                  ), 'setting');
  }
  elseif ($op == FB_OP_AJAX_EVENT) {
    if (fb_verbose() == 'extreme' && FALSE) { // disabled to prevent console not defined error.
      $session_id = session_id();
      $session_name = session_name();
      $return[] = "console.log('fb_devel.module extreme verbosity: original session_id is ' + Drupal.settings.fb_devel.session_name + ':' + Drupal.settings.fb_devel.session_id + ', session_id during FB_OP_AJAX_EVENT is $session_name:$session_id');";
      $fbu = fb_facebook_user($data['fb']);
      $return[] = "console.log('fb_facebook_user() during FB_OP_AJAX_EVENT is $fbu, data[event_data][fbu] is {$data[event_data][fbu]}');";
      $return[] = "console.log('_COOKIE[fbu_{$fb_app->apikey}] is " . $_COOKIE['fbu_' . $fb_app->apikey] . "');";
      $return[] = "FB_JS.reload();";
}

/**
 * Provides a page with useful debug info.
 *
 * @TODO - clean this up and rely less on drupal_set_message() and dpm().
  if (isset($_REQUEST['require_login']) && $_REQUEST['require_login'])
    $_fb->require_login();  // @TODO - find a way to do this with new api.
    // TODO: determine whether connect page or canvas.
Dave Cohen's avatar
Dave Cohen committed
    drupal_set_message(t("session name: " . session_name()));
Dave Cohen's avatar
Dave Cohen committed
    drupal_set_message(t("cookie domain: " . fb_settings(FB_SETTINGS_COOKIE_DOMAIN)));
Dave Cohen's avatar
Dave Cohen committed
    drupal_set_message(t("session id: " . session_id()));
    if (isset($_COOKIE['fbs_' . $_fb_app->apikey]))
      drupal_set_message(t("fbs_" . $_fb_app->apikey . ": " . $_COOKIE["fbs_" . $_fb_app->apikey]));
Dave Cohen's avatar
Dave Cohen committed
    drupal_set_message(t("<a href=\"!url\">processed link</a>, <a href=!url>unprocessed</a>", array('!url' => url('fb/devel'))));
    drupal_set_message(t("getUser() returns " . $_fb->getUser()));
    drupal_set_message(t("base_url: " . $GLOBALS['base_url']));
    drupal_set_message(t("base_path: " . $GLOBALS['base_path']));
    drupal_set_message(t("url() returns: " . url()));
  if ($fbu = fb_get_fbu($user)) {
    $path = "fb/devel/fbu/$fbu";
    drupal_set_message(t("Learn more about the current user at !link",
                         array('!link' => l($path, $path))));
  }

  dpm(fb_get_fbu($user), 'Facebook user via fb_get_fbu');
  //dpm($user, "Local user " . theme('username', $user));
  if (isset($GLOBALS['fb_connect_apikey'])) {
    drupal_set_message(t("fb_connect_apikey = " . $GLOBALS['fb_connect_apikey']));

  dpm(fb_settings(), 'fb_settings()');
  dpm($_COOKIE, 'cookie');
  dpm($_REQUEST, "Request");
  drupal_set_message(t("session_id returns " . session_id()));
/**
 * Provides a profile tab (FBML) with useful debug info.
Dave Cohen's avatar
Dave Cohen committed
 *
 */
function fb_devel_tab() {
  global $_fb, $_fb_app;
  global $user;

  $info['session_id'] = session_id();
  $info['session_name'] = session_name();
  $info['cookie domain'] = fb_settings(FB_SETTINGS_COOKIE_DOMAIN);

  // Tests for links
  $link_test = url(fb_scrub_urls($_REQUEST['q']), array('absolute' => TRUE));
  $info['link test'] = "<a href=\"$link_test\">link test (processed)</a>";
  $info['link test 2'] = "<a href='$link_test'>link test (not processed)</a>";

  //$info['fb_app'] = $_fb_app;
  //$info['fb'] = $_fb;
  $info['fb_settings'] = fb_settings();
  $info['REQUEST'] = $_REQUEST;
  $info['SESSION'] = $_SESSION;
  $info['COOKIE'] = $_COOKIE;

  if (isset($_fb)) {
    $info['fb->getSignedRequest()'] = $_fb->getSignedRequest();
    $fbu = fb_facebook_user();
      $info["fb->api(/$fbu)"] = $_fb->api('/' . $fbu);
    }
    catch (Exception $e) {
      $info["fb->api(/$fbu)"] = $e->getMessage();
    }
    if ($app_id = $_REQUEST['fb_sig_app_id']) {
      try {
        $info['fb->api(fb_sig_app_id)'] = $_fb->api($_REQUEST['fb_sig_app_id']);
      }
      catch (Exception $e) {
        $info['fb->api(fb_sig_app_id)'] = $e->getMessage();
      }
  print '<p>fb_devel.module tab</p>';
  foreach ($info as $key => $value) {
    print "<p>$key:\n";
    if (is_array($value)) {
      print '<pre>' . check_plain(print_r($value, 1)) . '</pre>';
    }
    elseif (is_object($value)) {
      print '<pre>' . check_plain(print_r($value, 1)) . '</pre>';
    }
    else {
      print '<pre>' . $value . '</pre>';
    }
    print "\n</p>\n\n";
  }
/**
 * A page which tests function which work with facebook user ids
 */
function fb_devel_fbu_page($fbu = NULL) {
    $info = $_fb->api($fbu, array('metadata' => 1));
    $output = "<p>Debug info about facebook id $fbu ({$info[name]}):</p>\n";
    $output .= "<img src=http://graph.facebook.com/$fbu/picture></img>";
    $output .= "<pre>" . print_r($info, 1) . "</pre>";

    foreach (array('statuses') as $connection) {
      try {
        if ($data = $_fb->api($fbu . '/' . $connection)) {
          $output .= "<p>$connection<pre>";
          $output .= print_r($data, 1);
          $output .= "</pre></p>\n\n";
        }
      }
      catch (FacebookApiException $e) {
        fb_log_exception($e, t('Failed to lookup %connection', array('%connection' => $fbu . '/' . $connection)));
      }
    try {
      $friends = $_fb->api($fbu . '/friends');
      //dpm($friends, "$fbu/friends returned");
      $items = array();
      foreach ($friends['data'] as $data) {
        $items[] = l($data['name'], "fb/devel/fbu/{$data[id]}");
      }
      if (count($items)) {
        $output .= "\n<p>Known friends:<ul><li>";
        $output .= implode("</li>\n  <li>", $items);
        $output .= "</li></ul></p>\n\n";
      }
    }
    catch (FacebookApiException $e) {
      fb_log_exception($e, t('Failed to lookup friends of facebook user %fbu', array('%fbu' => $fbu)));
    if (module_exists('fb_user')) {
      $local_friends = fb_user_get_local_friends($fbu);
      $items = array();
      foreach ($local_friends as $uid) {
        $account = user_load(array('uid' => $uid));
        $items[] = theme('username', $account);
      }
      if (count($items)) {
        $output .= "\n<p>Local friends:<ul><li>";
        $output .= implode("</li>\n  <li>", $items);
        $output .= "</li></ul></p>\n\n";
      }
    drupal_set_message(t("You have to specify a facebook user id."), 'error');

/**
 * Provide some information for testing AHAH and AJAX scenarios.
 */
function fb_devel_js() {
  $data = '<pre>';

  $data .= "session_name() = " . session_name() . "\n";
  $data .= "session_id() = " . session_id() . "\n";
  $data .= "REQUEST: " . dprint_r($_REQUEST, 1) . "\n";
  $data .= "SESSION: " . dprint_r($_SESSION, 1) . "\n";
  $data .= '</pre>';

  print drupal_json(array('status' => TRUE, 'data' => $data));
  exit();
}

function fb_devel_block($op = 'list', $delta = 0, $edit = array()) {
  if ($op == 'list') {
    // Provide two copies of same block, for iframe scenarios.
    $items[0]['info'] = t('Facebook Devel Page Info');
    $items[1]['info'] = t('Facebook Devel Page Info 2');
  elseif ($op == 'view') {
    if (user_access('access devel information')) {
      return array('subject' => t('Facebook Devel Info'),
                   'content' => drupal_get_form('fb_devel_info'));
    }
  global $user;
  global $base_url;
  global $base_path;

  $info = array();
    if (fb_settings(FB_SETTINGS_TYPE) == FB_SETTINGS_TYPE_CANVAS) {
      $info['Page Status'] = t('Serving canvas page.');
    elseif (fb_settings(FB_SETTINGS_TYPE) == FB_SETTINGS_TYPE_CONNECT) {
      $info['Page Status'] = t('Connected via Facebook Connect');
    }
Dave Cohen's avatar
Dave Cohen committed
    elseif (fb_settings(FB_SETTINGS_TYPE) == FB_SETTINGS_TYPE_PROFILE) {
      $info['Page Status'] = t('Serving profile tab');
    }
    elseif (!fb_settings(FB_SETTINGS_TYPE)) {
      $info['Page Status'] = t('Facebook SDK initialized. User is not logged into facebook or has not authorized application.');
      $info['Page Status'] = t('Global fb instance is set, but page type unknown (%type).',
                               array('%type' => fb_settings(FB_SETTINGS_TYPE),
                               ));
    $fbu = fb_facebook_user();
    $info['fb_facebook_user'] = $fbu;

    if (!$fbu) {
      $info['login button'] = theme('fb_login_button', 'Connect');
      $info['login link'] = "<a href=# onclick='FB.login(function(response) {alert(\"FB.login() success.\");}, {perms:Drupal.settings.fb.perms}); return false;'>fb login</a>";

    // Tests for link on canvas pages (iframe cookie test)
    //$link_test = url(fb_scrub_urls($_REQUEST['q']), array('absolute' => TRUE));
    //$info['link test'] = "<a href=\"$link_test\">link test (processed)</a>";
    //$info['link test 2'] = "<a href='$link_test'>link test (not processed)</a>";
    if ($fbu) {
      if (!fb_api_check_session($_fb)) {
        $info['fb_api_check_session()'] = t('Returned FALSE');
      }
      else {
        $info['fb_api_check_session()'] = t('Returned TRUE');
      }
    $info['Page Status'] = t('Not a canvas page.');
  // Use theme_username() rather than theme('username') because we want link to local user, even when FBML is enabled
  $info['local user'] = theme_username($user);
  $info['fb_get_fbu'] = fb_get_fbu($user->uid);
  $info['base_url'] = $base_url;
  $info['base_path'] = $base_path;
Dave Cohen's avatar
Dave Cohen committed
  $info['url() returns'] = url();
  $info['$_REQUEST[q] is'] = isset($_REQUEST['q']) ? $_REQUEST['q'] : NULL;
  $info['arg(0) is'] = arg(0);
  $info['arg(1) is'] = arg(1);
  $info['session_id'] = session_id();
  $info['session_name'] = session_name();
  $info['fbsettings(FB_SETTINGS_COOKIE_DOMAIN)'] = fb_settings(FB_SETTINGS_COOKIE_DOMAIN);
  $info['user'] = $GLOBALS['user'];
  $info['cookies'] = $_COOKIE;
    $info['signed_request'] = $_fb->getSignedRequest();
      $token = fb_get_token($_fb);
      $props = $_fb->api(array(
                           'method' => 'admin.getAppProperties',
                           'properties' => 'about_url', 'application_name',
                           'access_token' => $token,
                         ));
      $info['application properties'] = $props;
    }
    catch (FacebookApiException $e) {
      fb_log_exception($e, "failed to get app properties");
    }
    $info["fb->getSession()"] = $_fb->getSession();
    $info["fb->getSignedRequest()"] = $_fb->getSignedRequest();
    if ($fbu) {
      try {
        $info["fb->api($fbu)"] = $_fb->api($fbu, array(
                                             'access_token' => fb_get_token($_fb),
      }
      catch (FacebookApiException $e) {
        fb_log_exception($e, "failed to look up _fb->api($fbu)");
Dave Cohen's avatar
Dave Cohen committed
      }
  $form = array();
  foreach ($info as $key => $val) {
    if (is_string($val) || is_numeric($val) || !$val) {
      $form[] = array('#value' => t($key) . ' = ' . $val,
                      '#weight' => count($form),
                      '#suffix' => '<br/>',
      );
      $form[] = array(
        '#type' => 'fieldset',
        '#title' => t($key),
        '#collapsible' => TRUE,
        '#collapsed' => TRUE,
        '#weight' => count($form),
        'value' => array(
          '#prefix' => '<pre>',
          '#suffix' => '</pre>',
          '#type' => 'markup',
          '#value' => dprint_r($val, 1)),
      );
    }
  }
  // It's not really a form, but we like collapsible fieldsets
  return $form;
}

function fb_devel_user($op, &$edit, &$account, $category = NULL) {
  if ($op == 'view') {
    if (user_access('administer users') && user_access('access devel information')) {
      $account->content['fb_devel'] = array(
        '#type' => 'fieldset',
        '#title' => t('Drupal for Facebook Devel'),
        '#description' => t('Information from facebook API, visible only to administrators.'),
        '#collapsible' => TRUE,
        '#collapsed' => TRUE,
        '#weight' => 99,
      );
Dave Cohen's avatar
Dave Cohen committed
      foreach (fb_get_all_apps() as $fb_app) {
        $account->content['fb_devel'][$fb_app->label] = array(
          '#type' => 'fieldset',
Dave Cohen's avatar
Dave Cohen committed
          '#title' => $fb_app->title,
Dave Cohen's avatar
Dave Cohen committed
        if ($fbu = fb_get_fbu($account, $fb_app)) {
          $fb = fb_api_init($fb_app);
          try {
            $info = $fb->api("/$fbu");
            //$info = fb_users_getInfo(array($fbu), $fb, TRUE);
            $account->content['fb_devel'][$fb_app->label]['info'] = array(
              '#type' => 'markup',
              '#value' => dprint_r($info, 1),
Dave Cohen's avatar
Dave Cohen committed
            );
          }
          catch (Exception $e) {
            $account->content['fb_devel'][$fb_app->label]['#description'] = $e->getMessage();
            $account->content['fb_devel'][$fb_app->label]['info'] = array(
              '#type' => 'fieldset',
              '#title' => t('Failed to get info for !app.',
                            array('!app' => $fb_app->title)),
              '#collapsible' => TRUE,
              '#collapsed' => TRUE,
              'exception' => array(
                '#type' => 'markup',
                '#value' => dprint_r($e, 1),
              ),
Dave Cohen's avatar
Dave Cohen committed
            );
Dave Cohen's avatar
Dave Cohen committed
          $account->content['fb_devel'][$fb_app->label]['info'] = array(
            '#type' => 'markup',
            '#value' => t('No mapping to a facebook account.'),
          );
        }
      }
    }
  }
}
/**
 * Implementation of hook_cron().
 *
 * Remove obsolete data from {users} table.  Not a serious problem,
 * just cruft in the database which should never have been saved.
 * Clean it up.
 */
function fb_devel_cron() {
  $limit = 10;
  $result = db_query('SELECT * FROM {users} WHERE data LIKE "%\"app_specific\"%" OR data LIKE "%\"is_app_user\"%" OR data LIKE "%\"fbu\"%" LIMIT %d', $limit);
  while ($account = db_fetch_object($result)) {
    $data = unserialize($account->data);
    // Clean out the bogus data.
    foreach (array('app_specific', 'username', 'fbu', 'info') as $key) {
      unset($data[$key]);
    }
    db_query("UPDATE {users} SET data='%s' WHERE uid=%d",
             serialize($data), $account->uid);
    if (fb_verbose()) {
      print(t('Cleaned up data for user %name (%uid), it is now: !data',
              array('%name' => $account->name,
                    '%uid' => $account->uid,
                    '!data' => '<pre>' . print_r($data, 1) . '</pre>',
              )));
    }
  }
}


function fb_devel_fb_tab($op, $data, &$return) {
  // debug.
  if (fb_verbose() == 'extreme') {
    $return['fb_devel'] = array(
      '#type' => 'markup',
      '#value' => __FUNCTION__ . ':' . print_r($data, 1),
      '#prefix' => '<pre>',
      '#suffix' => '</pre>',
      '#weight' => 99,
    if ($data['profile_id']) {
      $return['fb_devel']['profile_id'] = array(
        '#type' => 'markup',
        '#value' => __FUNCTION__ . ':' . print_r($data['fb']->api($data['profile_id']), 1),
        '#prefix' => '<pre>',
        '#suffix' => '</pre>',
        '#weight' => 99,
      );
    }