Skip to content
fb_app.module 8.64 KiB
Newer Older
 * Implementation of Drupal for Facebook application.
 *
 * For maximum flexibility, DFF allows multiple implementations of the
 * "application" logic.  The important bit is our implementation of
 * hook_fb().  This module should suffice for just about everyone, but
 * if you want to implement your own, go right ahead.

define('FB_APP_REQ_API_KEY', 'fb_sig_api_key');

// Events that a facebook app might need to know about:
define('FB_APP_EVENT_POST_AUTHORIZE', 'post_authorize');
define('FB_APP_EVENT_POST_REMOVE', 'post_remove');
define('FB_APP_PATH_EVENT', 'fb_app/event');
define('FB_APP_PATH_EVENT_ARGS', 2);

define('FB_APP_OP_EVENT', 'fb_app_event');

function fb_app_fb($op, $data, &$return) {
  $fb = isset($data['fb']) ? $data['fb'] : NULL;
  $fb_app = isset($data['fb_app']) ? $data['fb_app'] : NULL;
Dave Cohen's avatar
Dave Cohen committed

    // Load app data, using the criteria passed in.
    $args = array();
    $where = array();
Dave Cohen's avatar
Dave Cohen committed

    // We also support these ways to query an app.  Columns in fb_app table.
               'fba_id' => '%d',
               'id' => '%d',
             ) as $key => $type) {
      if (isset($data[$key])) {
        $where[] = "$key = $type";
        $args[] = $data[$key];
      }
    }
    // Status is a special query.  Admin pages include disabled apps.
    if (isset($data['status'])) {
      $where[] = "status >= %d";
      $args[] = $data['status'];
Dave Cohen's avatar
Dave Cohen committed

    if (count($args)) {
      $fb_app = db_fetch_object(db_query("SELECT * FROM {fb_app} fba WHERE " . implode(' AND ', $where), $args));
    }
    if ($fb_app) {
  elseif ($op == FB_OP_GET_ALL_APPS) {
    // Return all known applications, including disabled.
    $result = db_query("SELECT fba.* FROM {fb_app} fba");
    while ($app = db_fetch_object($result)) {
      $return[] = $app;
    }
  }
  elseif ($op == FB_OP_POST_INIT) {
    // Include our admin hooks.
    if (fb_is_fb_admin_page()) {
      require drupal_get_path('module', 'fb_app') . '/fb_app.admin.inc';
    }
  elseif ($op == FB_OP_CURRENT_APP) {
    // Try to determine the current application from fb_settings.
    // If we fail, fb_canvas or fb_connect module will hopefully succeed.

    if (!$return && ($id = fb_settings(FB_SETTINGS_ID))) {
      $return = fb_get_app(array('id' => $id));
    }
    elseif (!$return && ($apikey = fb_settings(FB_SETTINGS_APIKEY))) {
      $return = fb_get_app(array('apikey' => $apikey));
/**
 * Implementation of hook_menu().
 */
function fb_app_menu() {
  // Allow facebook to notify on various events, like adding or removing an app.
  $items[FB_APP_PATH_EVENT . '/%/%'] = array(
    'access callback' => TRUE,
    'page callback' => 'fb_app_event_cb',
      FB_APP_PATH_EVENT_ARGS, // label
      FB_APP_PATH_EVENT_ARGS+1, // event type
Dave Cohen's avatar
Dave Cohen committed
    'type' => MENU_CALLBACK,
  // Administration.
  $items[FB_PATH_ADMIN . '/fb_app_create'] = array(
    'title' => 'Add Application',
    'description' => 'Host an application on this server.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('fb_app_edit_form'),
    'access arguments' => array(FB_PERM_ADMINISTER),
    'file' => 'fb_app.admin.inc',
    'type' => MENU_LOCAL_TASK,
    'weight' => -1,
  );
  $items[FB_PATH_ADMIN_APPS . '/%fb/fb_app'] = array(
    'title' => 'Edit',
    'description' => 'Edit Facebook Application',
    'page arguments' => array('fb_app_edit_form', FB_PATH_ADMIN_APPS_ARGS),
    'access arguments' => array(FB_PERM_ADMINISTER),
    'file' => 'fb_app.admin.inc',
    'weight' => -1,
    'type' => MENU_LOCAL_TASK,
Dave Cohen's avatar
Dave Cohen committed
  $items[FB_PATH_ADMIN_APPS . '/%fb/fb_app/delete'] = array(
    'title' => 'Delete',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('fb_app_admin_delete_confirm_form',
                              FB_PATH_ADMIN_APPS_ARGS),
Dave Cohen's avatar
Dave Cohen committed
    'access arguments' => array(FB_PERM_ADMINISTER),
    'file' => 'fb_app.admin.inc',
    'type' => MENU_CALLBACK,
  );
/**
 * Callback for FB_APP_PATH_EVENT.
Dave Cohen's avatar
Dave Cohen committed
 *
 * We don't act on the events directly.  We pass the information along via
 * hook_fb.  Other modules are thus notified of the event and can take action.
 */
function fb_app_event_cb($label, $event_type) {
  $fb_app = fb_get_app(array('label' => $label));
  if ($fb_app)
    $fb = fb_api_init($fb_app);
  fb_invoke(FB_APP_OP_EVENT, array(
      'fb_app' => $fb_app,
      'fb' => $fb,
      'event_type' => $event_type,
    ), NULL);
  // This page is called by facebook, not a user's browser.  User's should never see this.
  print('Thanks Facebook, for your fancy API!');

  // It's facebook calling us, not the user.  And fb_sig params make it look
  // like a canvas page, but it could be connect.  So bad idea to save session.
function fb_app_get_about_url($fb_app) {
  if ($fb_app->id)
Dave Cohen's avatar
Dave Cohen committed
    return url("http://www.facebook.com/apps/application.php",
               array('query' => array('id' => $fb_app->id)));
function theme_fb_app($fb_app) {
  // Get known properties
  $props_map = fb_invoke(FB_OP_LIST_PROPERTIES, array('fb_app' => $fb_app), array());
  $data = array(
    t('Label') => $fb_app->label,
    t('API Key') => $fb_app->apikey,
  );
  foreach ($props_map as $name => $key) {
    if (isset($fb_app->$key))
      $data[$name] = $fb_app->$key;
  }
  $output = theme('dl', $data);

/**
 * Implementation of hook_user.
 */
function fb_app_user($op, &$edit, &$account, $category = NULL) {
  $items = array();
  if ($op == 'view') {
    $apps = fb_get_all_apps();
    foreach ($apps as $fb_app) {
      // Learn this user's FB id
      $fbu = fb_get_fbu($account->uid, $fb_app);
      if ($fbu) {
        // The drupal user is a facebook user.  Now, learn more from facebook.
        $fb = fb_api_init($fb_app);
Dave Cohen's avatar
Dave Cohen committed
        if (fb_facebook_user($fb)) {
            $info = $fb->api(array('method' => 'users.getInfo',
                                   'uids' => array($fbu),
                                   'fields' => array(
                                     'about_me',
                                     'affiliations',
                                     'name',
                                     'is_app_user',
                                     'pic_big',
                                     'profile_update_time',
                                     'status',
                                   )));
          } catch (Exception $e) {
            fb_log_exception($e, "Failed to get Facebook user info for account $fbu");
          }
Dave Cohen's avatar
Dave Cohen committed
        if (isset($info) && count($info)) {
          $output = theme('fb_app_user_info', $fb_app, $info[0]);
          $items[$fb_app->label] = array(
            '#title' => $fb_app->title,
            '#type' => 'fieldset',
            'value' => array('#value' => $output),
          );
    if (count($items)) {
      $account->content['fb_app'] = $items;
      $account->content['fb_app']['#weight'] = 6; // Appear after history (user.module)
function theme_fb_app_user_info($fb_app, $info) {
  $output = '';
  if (isset($info['pic_big']))
    $output .= '<p><img src="'. $info['pic_big'] .'" /></p>';
  $fb_link = l($info['name'], 'http://www.facebook.com/profile.php', array(
                 'query' => 'id=' . $info['uid']));
Dave Cohen's avatar
Dave Cohen committed
    $output .= '<p>' .
      t('!fb_link uses %title', array(
          '!fb_link' => $fb_link,
Dave Cohen's avatar
Dave Cohen committed
          '%title' => $fb_app->title)) .
Dave Cohen's avatar
Dave Cohen committed
    $output .= '<p>'.
      t('!fb_link does not use %title', array(
          '!fb_link' => $fb_link,
Dave Cohen's avatar
Dave Cohen committed
          '%title' => $fb_app->title)) .
function fb_app_token_list($type = 'all') {
  if ($type == 'all' || $type == 'fb' || $type == 'fb_app') {
    $tokens['fb_app']['fb-app-label'] = t('Facebook application label');
    $tokens['fb_app']['fb-app-url'] = t('Facebook application canvas page URL');
  }
  return $tokens;
}

function fb_app_token_values($type = 'all', $object = NULL) {
Dave Cohen's avatar
Dave Cohen committed
  $values = array();
  if ($type == 'fb_app' && $object) {
    $fb_app = $object;
    $values['fb-app-label'] = $fb_app->label;
    $values['fb-app-url'] = 'http://apps.facebook.com/'. $fb_app->canvas;

function fb_app_theme() {
  return array(
    'fb_app_user_info' => array(
Dave Cohen's avatar
Dave Cohen committed
      'arguments' => array(