fb_permission.module in Drupal for Facebook 7.3
Same filename and directory in other branches
Code pertaining to Facebook's extended permissions. see http://wiki.developers.facebook.com/index.php/Extended_permissions
File
contrib/fb_permission.moduleView source
<?php
/**
* @file
* Code pertaining to Facebook's extended permissions.
* see http://wiki.developers.facebook.com/index.php/Extended_permissions
*/
/**
* Implements hook_permission().
*/
function fb_permission_permission() {
return array(
'edit own extended permissions' => array(
'title' => t('Edit own extended Facebook permissions'),
),
);
}
function fb_permission_access_perms($perms) {
if (is_string($perms)) {
$perms = explode(',', $perms);
}
$count = 0;
extract(fb_vars());
if ($fbu) {
try {
$api_data = fb_api('me/permissions');
$granted = $api_data['data'][0];
foreach ($perms as $perm) {
if (empty($granted[$perm]) || !$granted[$perm]) {
$auth_url = url('http://www.facebook.com/dialog/oauth/', array(
'query' => array(
'scope' => implode(',', $perms),
'client_id' => $fb_app->id,
'redirect_uri' => url(request_path(), array(
'absolute' => TRUE,
)),
'response_type' => 'token',
),
'absolute' => TRUE,
));
drupal_set_message(t('Additional permissions are required. <a href="!url">Grant permissions to continue</a>.', array(
'!url' => $auth_url,
)), 'error');
$GLOBALS['_fb_permission_extra_perms'] = $perms;
return FALSE;
}
else {
$count++;
}
}
} catch (Exception $e) {
fb_log_exception($e, __FUNCTION__);
}
}
else {
// User not connected.
// Ensure all connect buttons on this page include these perms.
$GLOBALS['_fb_permission_extra_perms'] = $perms;
drupal_set_message(t('Facebook Connect is required. !login_button', array(
'!login_button' => theme('fb_login_button', array(
'text' => t('Connect to continue'),
)),
)), 'error');
}
return $count == count($perms);
}
/**
* Helper function for menu item access check.
*/
function fb_permission_access_own($account, $perm) {
if (fb_facebook_user()) {
return $GLOBALS['user']->uid == $account->uid && user_access($perm);
}
}
// TODO: make this work.
function fb_permission_fb($op, $data, &$return) {
if ($op == FB_OP_JS && FALSE) {
// Disabled because the login popup not really working.
// fb.module is adding javascript to the page footer.
if (!empty($GLOBALS['_fb_permission_extra_perms'])) {
// We know from access hook that additional perms are required.
// Use javascript to ask for them.
$perms = array();
drupal_alter('fb_required_perms', $perms);
$perm_string = json_encode(implode(',', $perms));
$return['fb_permission_0'] = "debugger;";
$return['fb_permission'] = "FB.login(function(response){}, {scope:{$perm_string}});";
// Haven't figured out how to make this dialog work.
//$return['fb_permission'] = "FB.ui({method:'oauth',scope:$perm_string}, function(response){debugger;});";
//dpm($return);
}
}
}
/**
* Which permissions can we prompt for?
*
* @TODO - update this list and/or make it customizable.
*/
function fb_permission_map($fb) {
static $perms;
// http://developers.facebook.com/docs/reference/fql/permissions_info
$result = fb_fql_query($fb, "SELECT permission_name, header, summary FROM permissions_info WHERE 1", array(
'access_token' => fb_get_token($fb),
));
if (!isset($perms)) {
foreach ($result as $data) {
$perms[$data['permission_name']] = 'Allow %application to ' . strtolower($data['summary'] ? $data['summary'] : 'access ' . $data['header']);
}
}
return $perms;
}
/**
* Implements hook_fb_required_perms_alter().
*
* fb_connect.module can calls this to learn when perms to add to login-button.
*/
function fb_permission_fb_required_perms_alter(&$perms) {
global $_fb, $_fb_app;
$fb_app_data = fb_get_app_data($_fb_app);
if (isset($fb_app_data['fb_permission'])) {
$fb_permission_data = $fb_app_data['fb_permission'];
foreach ($fb_permission_data['prompt'] as $key => $value) {
if ($value) {
$perms[$key] = $key;
}
}
}
if (!empty($GLOBALS['_fb_permission_extra_perms'])) {
// Some page require additional perms, and it makes sense to include those on all connect buttons and links.
foreach ($GLOBALS['_fb_permission_extra_perms'] as $key) {
$perms[$key] = $key;
}
}
}
/**
* Implements hook_user_categories().
*/
function fb_permission_user_categories() {
$items = array();
// A tab for each application
foreach (fb_get_all_apps() as $fb_app) {
// TODO: limit only to apps which can be added to a user's account.
$items[] = array(
'name' => $fb_app->label,
'title' => $fb_app->title,
'access callback' => 'fb_permission_access_own',
'access arguments' => array(
1,
'edit own extended permissions',
),
'weight' => 2,
);
}
return $items;
}
/**
* Implements hook_form_FORM_ID_alter()
*/
function fb_permission_form_user_profile_form_alter(&$form, &$form_state) {
$category = $form['#user_category'];
$account = $form_state['user'];
// See if the category corresponds to a facebook app.
$fb_app = fb_get_app(array(
'label' => $category,
));
if ($fb_app) {
$fb = fb_api_init($fb_app);
$map = fb_permission_map($fb);
// All known permissions.
// Show only permissions we've configured for this app.
$fb_app_data = fb_get_app_data($fb_app);
$fb_permission_data = $fb_app_data['fb_permission'];
if (is_array($fb_permission_data['map'])) {
foreach ($fb_permission_data['map'] as $key => $value) {
if (!$value) {
unset($map[$key]);
}
}
}
/* Should not be necessary to wrap in serverfbml, as prompt-permission is documented as XFBML.
$form = array(
'perms' => array(
'#prefix' => '<fb:serverfbml><script type="text/fbml><fb:fbml>',
'#suffix' => '</fb:fbml></script></fb:serverfbml>',
),
);
*/
$t_args = array(
'%application' => $fb_app->title,
);
$weight = 0;
foreach ($map as $key => $text) {
$has_perm = FALSE;
try {
$has_perm = fb_call_method($fb, 'users.hasAppPermission', array(
'ext_perm' => $key,
'uid' => fb_get_fbu($account->uid, $fb_app),
));
} catch (Exception $e) {
fb_log_exception($e, t('Call to users.hasAppPermission(%key) failed.', array(
'%key' => $key,
)));
}
if (!$has_perm) {
if ('facebook has fixed fb:prompt-permission bugs' == FALSE) {
// Ideally, fb:prompt-permission would work. But it doesn't.
$form['perms'][$key] = array(
'#type' => 'markup',
'#value' => '<fb:prompt-permission perms="' . $key . '">' . t($text, $t_args) . '</fb:prompt-permission>',
'#weight' => $weight++,
'#suffix' => "<br/>\n",
);
}
else {
// Send user to facebook's extended permission page.
// This is weak. Would be better to use javascript or fb:prompt-permission.
$url = url(current_path(), array(
'absolute' => TRUE,
));
$form['perms'][$key] = array(
'#type' => 'markup',
'#value' => l(t($text, $t_args), "http://www.facebook.com/authorize.php", array(
'html' => TRUE,
'query' => array(
'api_key' => $fb_app->apikey,
'v' => '1.0',
'ext_perm' => $key,
'next' => $url,
'next_cancel' => $url,
),
)),
'#prefix' => '<p>',
'#suffix' => '</p>',
'#weight' => $weight++,
);
}
}
}
$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(
'html' => TRUE,
)),
'#prefix' => '<p>',
'#suffix' => "</p>\n",
'#weight' => $weight++,
);
unset($form['submit']);
unset($form['delete']);
}
}
/**
* Implements hook_form_alter().
*/
function fb_permission_form_alter(&$form, $state, $id) {
// Add settings to fb_app form
if (isset($form['fb_app_data'])) {
$fb_app = $form['#fb_app'];
$fb = fb_api_init($fb_app);
$fb_app_data = fb_get_app_data($fb_app);
$fb_permission_data = isset($fb_app_data['fb_permission']) ? $fb_app_data['fb_permission'] : NULL;
$form['fb_app_data']['fb_permission'] = array(
'#type' => 'fieldset',
'#title' => t('Facebook extended permissions'),
'#tree' => TRUE,
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' => t('Many permissions on the lists below <em>will not actually work!</em> This list is generated automatically, by querying facebook for all known extended permissions. Some of these are not supported or available only to privileged developers.<br/> <strong>Choose only <a target=_blank href=http://developers.facebook.com/docs/authentication/permissions/>permissions your application is actually allowed to use</a>. If you see an "invalid permission" error, return here and un-select that permission.</strong>'),
);
if ($fb_app && $fb_app->id) {
try {
// http://developers.facebook.com/docs/reference/fql/permissions_info
// Apparently, this query required an access token, so this won't work when creating an app, only when editing one.
$result = fb_fql_query($fb, "SELECT permission_name, header, summary FROM permissions_info WHERE 1", array(
'access_token' => fb_get_token($fb),
));
foreach ($result as $data) {
$options[$data['permission_name']] = $data['header'] . ' - ' . $data['summary'] . " ({$data['permission_name']})";
}
// First the perms that will be required.
if (!isset($fb_permission_data['prompt'])) {
$fb_permission_data['prompt'] = array();
}
$form['fb_app_data']['fb_permission']['prompt'] = array(
'#type' => 'checkboxes',
'#title' => t('Required extended permissions'),
'#options' => $options,
'#default_value' => $fb_permission_data['prompt'],
'#description' => t('Prompt users when they first authorize the application. Select only the most important features.'),
);
// Next the optional perms.
if (!isset($fb_permission_data['map'])) {
$fb_permission_data['map'] = array();
}
$form['fb_app_data']['fb_permission']['map'] = array(
'#type' => 'checkboxes',
'#title' => t('Optional extended permissions'),
'#options' => $options,
'#default_value' => $fb_permission_data['map'],
'#description' => t('Which extended permissions does this application use? Users will be able to grant these permissions on their user edit pages.'),
);
} catch (Exception $e) {
if ($fb_app->apikey) {
// If there's an apikey, this is an unexpected error.
drupal_set_message(t('Failed to get extended permissions. %msg', array(
'%msg' => $e
->getMessage(),
)), 'warning');
}
// Drupal will not display this properly in the collapsed fieldset. Not sure how to fix!
$form['fb_app_data']['fb_permission']['msg'] = array(
'#type' => 'markup',
'#value' => t('Failed to get extended permissions from facebook. Submit this form, then click "edit" to see extended permission options.'),
);
}
}
else {
// App not yet configured.
$form['fb_app_data']['fb_permission']['#description'] = t('First save this form, then click "edit" to return here and see extended permission options.');
$form['fb_app_data']['fb_permission']['#collapsed'] = FALSE;
}
}
}
Functions
Name | Description |
---|---|
fb_permission_access_own | Helper function for menu item access check. |
fb_permission_access_perms | |
fb_permission_fb | |
fb_permission_fb_required_perms_alter | Implements hook_fb_required_perms_alter(). |
fb_permission_form_alter | Implements hook_form_alter(). |
fb_permission_form_user_profile_form_alter | Implements hook_form_FORM_ID_alter() |
fb_permission_map | Which permissions can we prompt for? |
fb_permission_permission | Implements hook_permission(). |
fb_permission_user_categories | Implements hook_user_categories(). |