fb_app.module in Drupal for Facebook 6.2
Same filename and directory in other branches
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.
File
fb_app.moduleView source
<?php
/**
* @file
* 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');
/**
* Implementation of hook_fb().
*/
function fb_app_fb($op, $data, &$return) {
$fb = isset($data['fb']) ? $data['fb'] : NULL;
$fb_app = isset($data['fb_app']) ? $data['fb_app'] : NULL;
if ($op == FB_OP_GET_APP) {
// Load app data, using the criteria passed in.
$args = array();
$where = array();
// This implementation uses 'label' as the unique id.
foreach (array(
FB_SETTINGS_CB,
FB_SETTINGS_LABEL,
) as $key) {
if (isset($data[$key]) && is_numeric($data[$key])) {
// DEPRECATED
// for backward compatibility we accept the nid, but that will go away in a later release!
$where[] = "(label = '%s' || nid = '%d')";
$args[] = $data[$key];
$args[] = $data[$key];
}
elseif (isset($data[$key])) {
// This is the right way, using label.
$where[] = "label = '%s'";
$args[] = $data[$key];
}
}
// We also support these ways to query an app.
foreach (array(
'fba_id' => '%d',
'apikey' => "'%s'",
'nid' => '%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'];
}
else {
$where[] = "status > 0";
}
if (count($args)) {
$fb_app = db_fetch_object(db_query("SELECT * FROM {fb_app} fba WHERE " . implode(' AND ', $where), $args));
}
if ($fb_app) {
$return = $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) {
// Normally the current app is determined by fb_canvas or fb_connect, unless it is our event callback.
if (arg(0) == 'fb_app' && !$return) {
if (function_exists('fb_settings')) {
if (fb_settings(FB_SETTINGS_TYPE) == FB_SETTINGS_TYPE_CANVAS && ($apikey = fb_settings(FB_SETTINGS_APIKEY))) {
$return = fb_get_app(array(
'apikey' => $apikey,
));
}
}
}
}
}
/**
* Implementation of hook_menu().
*/
function fb_app_menu() {
$items = array();
// 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',
'page arguments' => array(
FB_APP_PATH_EVENT_ARGS,
),
'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' => 'Add Facebook Application',
'page callback' => 'drupal_get_form',
'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,
);
$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,
),
'access arguments' => array(
FB_PERM_ADMINISTER,
),
'file' => 'fb_app.admin.inc',
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Callback for FB_APP_PATH_EVENT.
*
* 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($event_type) {
// Events are passed 'fb_sig' params, so globals should be set.
global $_fb, $_fb_app;
if (!$_fb_app) {
drupal_not_found();
return;
}
watchdog('fb_app_event_cb', print_r($_REQUEST, 1));
// debug
watchdog('fb_app_event_cb', 'session id is ' . session_id());
fb_invoke(FB_APP_OP_EVENT, array(
'event_type' => $event_type,
'fb_app' => $_fb_app,
'fb' => $_fb,
), 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.
session_save_session(FALSE);
exit;
}
function fb_app_get_about_url($fb_app) {
if ($fb_app->id) {
return url("http://www.facebook.com/apps/application.php", array(
'query' => array(
'id' => $fb_app->id,
),
));
}
}
// Not currently used, AFAIK.
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);
return $output;
}
/**
* 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, FB_FBU_ANY);
if (fb_facebook_user($fb)) {
try {
$info = $fb->api_client
->users_getInfo(array(
$fbu,
), 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}");
}
}
if (isset($info) && count($info)) {
// Is this working properly??? TODO!
$output = theme('fb_app_user_info', $fb_app, $info[0]);
$items[$fb_app->label] = array(
'title' => $fb_app->title,
'value' => $output,
'class' => 'fb_app',
);
}
else {
fb_report_errors($fb);
}
}
}
if (count($items)) {
return array(
t('Facebook') => $items,
);
}
}
}
function theme_fb_app_user_info($fb_app, $info) {
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'],
));
if ($info['is_app_user']) {
$output .= '<p>' . t('!fb_link uses %title', array(
'!fb_link' => $fb_link,
'%title' => $fb_app->title,
)) . '</p>';
}
else {
$output .= '<p>' . t('!fb_link does not use %title', array(
'!fb_link' => $fb_link,
'%title' => $fb_app->title,
)) . '</p>';
}
return $output;
}
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) {
$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;
}
return $values;
}
Functions
Name | Description |
---|---|
fb_app_event_cb | Callback for FB_APP_PATH_EVENT. |
fb_app_fb | Implementation of hook_fb(). |
fb_app_get_about_url | |
fb_app_menu | Implementation of hook_menu(). |
fb_app_token_list | |
fb_app_token_values | |
fb_app_user | Implementation of hook_user. |
theme_fb_app | |
theme_fb_app_user_info |
Constants
Name | Description |
---|---|
FB_APP_EVENT_POST_AUTHORIZE | |
FB_APP_EVENT_POST_REMOVE | |
FB_APP_OP_EVENT | |
FB_APP_PATH_EVENT | |
FB_APP_PATH_EVENT_ARGS | |
FB_APP_REQ_API_KEY | @file Implementation of Drupal for Facebook application. |