nid . '/' . FB_APP_PATH_EVENT, array('absolute' => TRUE)) . '/';
$return['uninstall_url'] = $url . FB_APP_EVENT_POST_REMOVE;
$return['authorize_url'] = $url . FB_APP_EVENT_POST_AUTHORIZE;
}
else if ($op == FB_OP_LIST_PROPERTIES) {
$return[t('Application Name')] = 'application_name';
$return[t('About URL')] = 'about_url';
$return[t('Post-Authorize Callback URL')] = 'authorize_url';
$return[t('Post-Remove Callback URL')] = 'uninstall_url';
}
}
/**
* Implementation of something_load() to create custom loader for hook_menu().
*
* see "Defining your own wildcard loader" - http://drupal.org/node/209056
* passing $nid not needed if menu_get_object() were to work.
*/
function fb_app_nid_load($nid) {
$node = node_load($nid);
if ($node->type == 'fb_app') {
return $node;
}
}
/**
* 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',
'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) {
fb_invoke(FB_APP_OP_EVENT, array('event_type' => $event_type,
'fb_app' => $GLOBALS['fb_app'],
'fb' => $GLOBALS['fb']));
// This page is called by facebook, not a user's browser.
print('Thanks Facebook, for your fancy API!');
// Problems if we save session during Facebook Connect, because the event callback's share session with normal pages.
session_save_session(FALSE);
exit();
}
/**
* hook_node_info.
*/
function fb_app_node_info() {
return array('fb_app' =>
array('name' => t('Facebook Application'),
'module' => 'fb_app',
'description' => t('Information such as apikey and secret for a facebook.com application.'),
'help' => t('Configure the behavior of your Facebook Application.'),
),
);
}
function fb_app_access($op, $node, $account) {
if (user_access('administer fb apps', $account))
return TRUE;
if ($op == 'create' && user_access('create fb apps', $account))
return TRUE;
else if ($op == 'update' || $op == 'delete') {
if ($node->uid == $account->uid &&
user_access('edit own fb apps', $account))
return TRUE;
}
}
function fb_app_perm() {
return array('administer fb apps', 'create fb apps', 'edit own fb apps');
}
function fb_app_form(&$node, &$param) {
// Helpful link
if (!$node->nid) {
drupal_set_message(t("Before completing this form, create your application on Facebook.",
array('!url' => 'http://www.facebook.com/developers/editapp.php?new')));
}
$form = array();
$type = node_get_types('type', $node);
// We need to define form elements for the node's title and body.
$form['title'] = array('#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#required' => TRUE,
'#default_value' => $node->title,
'#weight' => -5,
'#description' => t('Identifies the application to site administrators.'),
);
// We want the body and filter elements to be adjacent. We could try doing
// this by setting their weights, but another module might add elements to the
// form with the same weights and end up between ours. By putting them into a
// sub-array together, we're able force them to be rendered together.
$form['body_filter']['body'] =
array('#type' => 'textarea',
'#title' => check_plain($type->body_label),
'#default_value' => $node->body,
'#required' => FALSE,
'#description' => 'A brief description of the application.',
);
$form['body_filter']['filter'] = filter_form($node->format);
// Now we define the form elements specific to our node type.
$form['fb_app'] = array('#tree' => TRUE,
'#weight' => -4,
'#validate' => array('fb_app_validate_fb_app' => array()),
);
$form['fb_app']['label'] = array('#type' => 'textfield',
'#title' => t('Label'),
'#required' => TRUE,
'#default_value' => $node->fb_app->label,
'#description' => t('Used behind the scenes, for naming roles, styles, etc. Use no spaces or weird characters.
Working with multiple copies of a site (i.e. development, staging, production)? Use the same label for each. Node id and apikey will change from server to server, but the label remains the same.'),
);
$form['fb_app']['apikey'] = array('#type' => 'textfield',
'#title' => t('API Key'),
'#required' => TRUE,
'#default_value' => $node->fb_app->apikey,
'#description' => t('Facebook will generate this value when you create the application.'),
);
$form['fb_app']['secret'] = array('#type' => 'textfield',
'#title' => t('Secret'),
'#required' => TRUE,
'#default_value' => $node->fb_app->secret,
'#description' => t('Facebook will generate this value when you create the application.'),
);
$form['fb_app']['id'] = array('#type' => 'textfield',
'#title' => t('Facebook App ID'),
'#required' => FALSE,
'#default_value' => $node->fb_app->id,
'#description' => t('To learn this number, visit your app\'s About Page (or other links from Facebook\'s Developer App). The URL will end in ?id=1234... Enter the number that follows "?id=" here.'),
);
// fb_app_data is a placeholder to make it easier for other module to attach
// various settings to the node.
$form['fb_app_data'] = array('#tree' => TRUE);
// Add our own fields to fb_app_data. Other modules use hook_form_alter to do this.
$fb_app_data = fb_app_get_data($node->fb_app);
$data = $fb_app_data['fb_app'];
if (!$data)
$data = array('set_app_props' => TRUE); // defaults
$form['fb_app_data']['fb_app']['set_app_props'] = array(
'#type' => 'checkbox',
'#title' => t('Set Application Properties Automatically'),
'#description' => t('Automatically update Facebook settings for this application. Disable to prevent customized settings from being overwritten.'),
'#default_value' => $data['set_app_props'],
);
return $form;
}
function fb_app_validate($node) {
// TODO: check label is unique, and role name will be unique.
// check apikey is unique, canvas page is unique
$fb_app = (object) $node->fb_app;
fb_app_get_app_properties($fb_app);
if (!$fb_app->application_name) {
form_set_error('fb_app][apikey', t('Unable to get application properties. Confirm both apikey and secret.'));
}
}
function fb_app_validate_fb_app() {
//dpm(func_get_args(), 'fb_app_validate_fb_app');
}
/**
* Implementation of hook_load().
*/
function fb_app_load($node) {
$fb_app = db_fetch_object(db_query('SELECT * FROM {fb_app} WHERE nid=%d',
$node->nid));
$fb_app_data = fb_app_get_data($fb_app);
return array('fb_app' => $fb_app,
'fb_app_data' => $fb_app_data,
);
}
function fb_app_view($node, $teaser=FALSE, $page=FALSE) {
$node = node_prepare($node, $teaser);
$fb_app = (object) $node->fb_app; // cast in case of preview
fb_app_get_app_properties($fb_app);
// Perhaps this info should be hidden, unless user can edit node.
if (user_access('administer fb apps')) {
if(isset($fb_app->edit_url)) {
$node->content['edit_link'] = array(
'#value' => '
' . t('Edit this application on Facebook.', array('!url' => $fb_app->edit_url)) . '
', '#type' => 'markup', ); } $node->content['fb_app'] = array('#value' => theme('fb_app', $fb_app), '#weight' => 1); } return $node; } function fb_app_theme() { return array( 'fb_app' => array( 'arguments' => array('data' => NULL), ), 'dl' => array( 'arguments' => array('items' => NULL), ), 'fb_app_user_info' => array( 'arguments' => array('fb_app' => NULL, 'info' => NULL), ), ); } 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))); } 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, t('Secret') => $fb_app->secret, ); foreach ($props_map as $name => $key) { if (isset($fb_app->$key)) $data[$name] = $fb_app->$key; } $output = theme('dl', $data); return $output; } // this belongs elsewhere function theme_dl($items) { if (count($items)) { $output = "' . t('!fb_link uses %title', array('!fb_link' => $fb_link, '%title' => $fb_app->title)) . '
'; else $output .= ''. t('!fb_link does not use %title', array('!fb_link' => $fb_link, '%title' => $fb_app->title)) . '
'; return $output; } function fb_app_token_list($type = 'all') { if ($type == 'all' || $type == 'fb' || $type == 'fb_app') { $tokens['fb_app']['fb-app-nid'] = t('Facebook application ID'); $tokens['fb_app']['fb-app-title'] = t('Facebook application title'); $tokens['fb_app']['fb-app-url'] = t('Facebook application URL (base path)'); } return $tokens; } function fb_app_token_values($type = 'all', $object = NULL) { $values = array(); if ($type == 'fb_app' && $object) { $fb_app = $object; $values['fb-app-title'] = $fb_app->title; $values['fb-app-nid'] = $fb_app->nid; $values['fb-app-url'] = 'http://apps.facebook.com/'.$fb_app->canvas; } return $values; } ?>