| 1 |
<?php
|
| 2 |
/**
|
| 3 |
* @file
|
| 4 |
*
|
| 5 |
* This module manages an infinite session for each Facebook App.
|
| 6 |
* http://wiki.developers.facebook.com/index.php/Infinite_session_keys
|
| 7 |
*/
|
| 8 |
|
| 9 |
/**
|
| 10 |
* hook_fb.
|
| 11 |
*/
|
| 12 |
function fb_infinite_fb($op, $data, &$return) {
|
| 13 |
$fb = $data['fb'];
|
| 14 |
$fb_app = $data['fb_app'];
|
| 15 |
|
| 16 |
if ($op == FB_OP_GET_INFINITE_SESSION) {
|
| 17 |
// The fb module is asking for infinite session login information.
|
| 18 |
// This module knows it, so we provide it.
|
| 19 |
$fb_app_data = fb_app_get_data($fb_app);
|
| 20 |
$fb_infinite_data = $fb_app_data['fb_infinite'];
|
| 21 |
if ($fb_infinite_data['fbu'] && $fb_infinite_data['key'])
|
| 22 |
// Return array with FB id and apikey.
|
| 23 |
$return = array($fb_infinite_data['fbu'], $fb_infinite_data['key']);
|
| 24 |
}
|
| 25 |
}
|
| 26 |
|
| 27 |
/**
|
| 28 |
* hook_menu
|
| 29 |
*/
|
| 30 |
function fb_infinite_menu() {
|
| 31 |
$items['fb/infinite/display'] =
|
| 32 |
array('title' => t('Facebook session information'),
|
| 33 |
'page callback' => 'fb_infinite_display_page',
|
| 34 |
'access callback' => TRUE,
|
| 35 |
'type' => MENU_CALLBACK,
|
| 36 |
);
|
| 37 |
|
| 38 |
$items['node/%fb_infinite/fb/infinite/test'] =
|
| 39 |
array('title' => 'Infinite session test',
|
| 40 |
'page callback' => 'fb_infinite_test_page',
|
| 41 |
'page arguments' => array(1),
|
| 42 |
'access callback' => 'node_access',
|
| 43 |
'access arguments' => array('update', 1),
|
| 44 |
'type' => MENU_LOCAL_TASK,
|
| 45 |
);
|
| 46 |
|
| 47 |
return $items;
|
| 48 |
}
|
| 49 |
|
| 50 |
|
| 51 |
/**
|
| 52 |
* Implementation of hook_load to create custom loader for hook_menu
|
| 53 |
* Checks a fb_app nid to see if infinite session is configured
|
| 54 |
*
|
| 55 |
* see "Defining your own wildcard loader" - http://drupal.org/node/209056
|
| 56 |
* passing $nid not needed if menu_get_object were to work
|
| 57 |
*/
|
| 58 |
function fb_infinite_load($nid) {
|
| 59 |
$fb_app = fb_get_app(array('nid' => $nid));
|
| 60 |
if ($fb_app) {
|
| 61 |
// Only allow menu item if infinite session is configured.
|
| 62 |
$fb_app_data = fb_app_get_data($fb_app);
|
| 63 |
$fb_infinite_data = $fb_app_data['fb_infinite'];
|
| 64 |
if (isset($fb_infinite_data['key'])) {
|
| 65 |
return $fb_app;
|
| 66 |
}
|
| 67 |
}
|
| 68 |
}
|
| 69 |
|
| 70 |
/**
|
| 71 |
* Implementation of hook_form_alter.
|
| 72 |
*/
|
| 73 |
function fb_infinite_form_alter(&$form, &$form_state, $form_id) {
|
| 74 |
//drupal_set_message("fb_infinite_form_alter($form_id) " . dpr($form, 1)) . dpr($form_state, 1));
|
| 75 |
|
| 76 |
// Add our settings to the fb_app edit form.
|
| 77 |
if (is_array($form['fb_app_data'])) {
|
| 78 |
$node = $form['#node'];
|
| 79 |
$fb_app_data = fb_app_get_data($node->fb_app);
|
| 80 |
$fb_infinite_data = $fb_app_data['fb_infinite'];
|
| 81 |
|
| 82 |
$form['fb_app_data']['fb_infinite'] =
|
| 83 |
array('#type' => 'fieldset',
|
| 84 |
'#collapsible' => TRUE,
|
| 85 |
'#collapsed' => TRUE,
|
| 86 |
'#title' => t('Facebook infinite session settings'),
|
| 87 |
'#description' => t('An infinite session key is required to access the Facebook API from non-canvas pages. For example, a cron job.'));
|
| 88 |
if (!$node->nid) {
|
| 89 |
// User must save apikey and secret before we can prompt for infinite session key.
|
| 90 |
$form['fb_app_data']['fb_infinite']['message'] =
|
| 91 |
array('#value' => '<p>'.t('Save your apikey and secret settings first. Then return here to set up the infinite session.').'</p>');
|
| 92 |
}
|
| 93 |
else {
|
| 94 |
if ($node->fb_app->canvas) {
|
| 95 |
$form['fb_app_data']['fb_infinite']['help'] = array('#value' => t('<a href=!url target=_blank>Get your session key</a>. If prompted to log in, be sure to check the box that prevents your session from expiring.',
|
| 96 |
array('!url' => "http://apps.facebook.com/".$node->fb_app->canvas."/fb/infinite/display")),
|
| 97 |
'#prefix' => '<p>',
|
| 98 |
'#suffix' => '</p>');
|
| 99 |
}
|
| 100 |
else {
|
| 101 |
$form['fb_app_data']['fb_infinite']['help'] = array('#value' => t('Configure canvas pages for additional help generating an infinite session key.'),
|
| 102 |
'#prefix' => '<p>',
|
| 103 |
'#suffix' => '</p>');
|
| 104 |
}
|
| 105 |
|
| 106 |
$form['fb_app_data']['fb_infinite']['fbu'] =
|
| 107 |
array('#type' => textfield,
|
| 108 |
'#title' => t('Facebook User ID'),
|
| 109 |
'#default_value' => $fb_infinite_data['fbu'],
|
| 110 |
);
|
| 111 |
$form['fb_app_data']['fb_infinite']['key'] =
|
| 112 |
array('#type' => textfield,
|
| 113 |
'#title' => t('Infinite Session Key'),
|
| 114 |
'#default_value' => $fb_infinite_data['key'],
|
| 115 |
);
|
| 116 |
|
| 117 |
/* so far, I can't get this to work.
|
| 118 |
$form['fb_app_data']['fb_infinite']['code'] =
|
| 119 |
array('#type' => textfield,
|
| 120 |
'#title' => t('One-time code'),
|
| 121 |
'#description' => t('Get a one-time code from facebook, <a href=!url target=_blank>here</a>.',
|
| 122 |
array('!url' => "http://www.facebook.com/code_gen.php?v=1.0&api_key=" . $node->fb_app->apikey)),
|
| 123 |
);
|
| 124 |
*/
|
| 125 |
}
|
| 126 |
}
|
| 127 |
}
|
| 128 |
|
| 129 |
function fb_infinite_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
|
| 130 |
if ($node->type == 'fb_app') {
|
| 131 |
if ($op == 'presave') {
|
| 132 |
$fb_app_data = $node->fb_app_data;
|
| 133 |
$fb_infinite_data = $fb_app_data['fb_infinite'];
|
| 134 |
|
| 135 |
// This is an attempt to make the one-time code work. I can't figure it out.
|
| 136 |
// http://forum.developers.facebook.com/viewtopic.php?pid=76361#p76361
|
| 137 |
if ($code = $fb_infinite_data['code']) {
|
| 138 |
drupal_set_message("code is $code");
|
| 139 |
$fb = fb_api_init($node->fb_app, FB_FBU_CURRENT); // Does not set user.
|
| 140 |
|
| 141 |
$session = $fb->api_client->auth_getSession($code);
|
| 142 |
//dpm($session, "auth_getSession returned");
|
| 143 |
}
|
| 144 |
}
|
| 145 |
}
|
| 146 |
}
|
| 147 |
|
| 148 |
|
| 149 |
/**
|
| 150 |
* Menu callback. Ensures the user is logged in and displays user id and
|
| 151 |
* session key.
|
| 152 |
*/
|
| 153 |
function fb_infinite_display_page() {
|
| 154 |
global $fb, $fb_app;
|
| 155 |
|
| 156 |
if (!$fb_app) {
|
| 157 |
drupal_set_message(t('This page must be viewed as a Facebook canvas page.'), 'error');
|
| 158 |
drupal_not_found();
|
| 159 |
exit();
|
| 160 |
}
|
| 161 |
|
| 162 |
$fbu = $fb->require_login();
|
| 163 |
if ($fb->api_client->users_hasAppPermission('offline_access')) {
|
| 164 |
$output .= '<p>'.t('Facebook user id: %fbu',
|
| 165 |
array('%fbu' => $fb->api_client->users_getLoggedInUser())). '</p>';
|
| 166 |
$output .= '<p>'.t('Facebook session key: %session',
|
| 167 |
array('%session' => $fb->api_client->session_key)). '</p>';
|
| 168 |
$output .= '<p>'.t('Use the values above when configuring the infinite session of your Facebook App.').'</p>';
|
| 169 |
}
|
| 170 |
else {
|
| 171 |
$output .= '<p><fb:prompt-permission perms="offline_access">' . t('Click here for a session that will not expire.') . '</fb:prompt-permission></p>';
|
| 172 |
$output .= '<p>' . t('Refresh your browser after clicking the above link.') . '</p>';
|
| 173 |
}
|
| 174 |
return $output;
|
| 175 |
}
|
| 176 |
|
| 177 |
/**
|
| 178 |
* Menu callback to test infinite session values.
|
| 179 |
*/
|
| 180 |
function fb_infinite_test_page($fb_app) {
|
| 181 |
//dpm(func_get_args(), "fb_infinite_test_page");
|
| 182 |
|
| 183 |
if ($GLOBALS['fb']) {
|
| 184 |
$url = $GLOBALS['fb_old_base_url'] . "?q=".$_GET['q'];
|
| 185 |
return t('Do not use this page from a canvas page. Try !link.',
|
| 186 |
array('!link' => l($url, $url)));
|
| 187 |
}
|
| 188 |
|
| 189 |
$fb = fb_api_init($fb_app, FB_FBU_INFINITE_SESSION);
|
| 190 |
if ($fb) {
|
| 191 |
$fbu = $fb->api_client->users_getLoggedInUser();
|
| 192 |
if ($fbu) {
|
| 193 |
$info = $fb->api_client->users_getInfo(array($fbu),
|
| 194 |
array('about_me',
|
| 195 |
'affiliations',
|
| 196 |
'name',
|
| 197 |
'is_app_user',
|
| 198 |
'pic_big',
|
| 199 |
'profile_update_time',
|
| 200 |
'status',
|
| 201 |
));
|
| 202 |
$info = $info[0];
|
| 203 |
$fb_link = l($info['name'], 'http://www.facebook.com/profile.php',
|
| 204 |
array('query' => 'id='.$info['uid']));
|
| 205 |
|
| 206 |
drupal_set_message(t('Infinite session key is working.'));
|
| 207 |
$output .= '<p>'.t('Facebook infinite session user: !user',
|
| 208 |
array('!user' => $fb_link)) . '</p>';
|
| 209 |
$output .= '<p>'.t('This page cannot test that the session key will never expire. If your cron jobs start to fail, return here to test the login again.').'</p>';
|
| 210 |
return $output;
|
| 211 |
}
|
| 212 |
else {
|
| 213 |
drupal_set_message(t('Infinite session key test failed.'), 'error');
|
| 214 |
// TODO: provide helpful hints of how to fix the problem.
|
| 215 |
$output .= '<p>'.t('Unable to log into Facebook using infinite session key.').'</p>';
|
| 216 |
}
|
| 217 |
}
|
| 218 |
else {
|
| 219 |
drupal_set_message('Infinite session key test failed.', 'error');
|
| 220 |
// TODO: provide helpful hints of how to fix the problem.
|
| 221 |
$output .= '<p>'.t('Unable to log into Facebook using infinite session key.').'</p>';
|
| 222 |
}
|
| 223 |
|
| 224 |
return $output;
|
| 225 |
}
|
| 226 |
|