Newer
Older
Dave Cohen
committed
<?php
Dave Cohen
committed
/**
* @file
* Support for Facebook Connect features
*
* Note that Facebook connect will work properly only with themes that are
* Facebook Connect aware.
*/
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
function fb_connect_menu($may_cache) {
$items = array();
if ($may_cache) {
$items[] = array('path' => 'fb/connect/receiver',
'callback' => 'fb_connect_receiver',
'type' => MENU_CALLBACK,
'access' => TRUE,
);
$items[] = array('path' => 'fb/connect/expire',
'callback' => 'fb_connect_expire',
'type' => MENU_CALLBACK,
'access' => TRUE);
}
return $items;
}
/**
* Without a receiver file, cross-domain javascript will not work.
*
* In their infinite wisdom, facebook has decreed that the URL for
* this static page be in the same place as the app's callback URL.
* So we have to make a Drupal callback for what would otherwise be a
* simple file.
*/
function fb_connect_receiver() {
$output = '
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<body>
<!-- http://wiki.developers.facebook.com/index.php/Cross_Domain_Communication_Channel -->
<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver.debug.js" type="text/javascript"></script>
</body>
</html>
';
print $output;
exit();
die();
}
/**
* First attempt to get rid of Facebook's cookies. Not working
* as desired, so this is deprecated. Instead we redirect user on logout.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
*/
function fb_connect_expire($apikey) {
$fb_app = fb_get_app(array('apikey' => $apikey));
$fb = fb_api_init($fb_app, FB_FBU_CURRENT);
//$result = $fb->expire_session();
// http://forum.developers.facebook.com/viewtopic.php?id=21879
// Use next parameter to return to our logout.
//drupal_goto("http://www.facebook.com/logout.php?app_key={$fb_app->apikey}&session_key={$session_key}&next=" . url('logout', NULL, NULL, TRUE));
drupal_goto('logout');
}
/**
* Prepare for fbConnect use. Because a single Drupal might support
* multiple apps, we don't know in advance which is the fbConnect app.
* Theoretically, it might be possible to simultaneously use multiple
* apps and fbConnect, but my suspicion is facebook would throw a
* total hissy-fit if you tried.
*/
function fb_connect_app_init($fb_app) {
$fb = fb_api_init($fb_app, FB_FBU_CURRENT);
$fbu = $fb->get_loggedin_user();
if ($fbu) {
// The user has authorized the app and we now know something about them. Use a hook to trigger the actions of other modules.
fb_invoke(FB_OP_APP_IS_AUTHORIZED, array('fbu' => $fbu,
'fb_app' => $fb_app,
'fb' => $fb));
}
// Store state in session
if (!$_SESSION['fb_connect']) {
$_SESSION['fb_connect'] = array();
}
$_SESSION['fb_connect'][$fb_app->apikey] = $fbu;
return $fb;
}
/**
* Are we already logged in to fbConnect?
*/
function fb_connect_already_loggedin($fb_app) {
if ($_SESSION['fb_connect'])
return $_SESSION['fb_connect'][$fb_app->apikey];
return FALSE;
}
/**
* Which apps are fbConnect enabled?
*/
function fb_connect_enabled_apps() {
// We do a bit of work for each enabled app, so really we want to restrict this list to only apps which have been "turned on".
// But for now we're lazy and just get the list of all apps.
$apps = fb_get_all_apps();
return $apps;
}
function fb_connect_fb($op, $data, &$return) {
//dpm(func_get_args(), "fb_connect_fb($op)");
}
/**
* Implementation of hook_user
*
* On logout, redirect the user so facebook can expire their session.
* Should be a facebook API to do this, but there's none I know of.
*/
function fb_connect_user($op, &$edit, &$account, $category = NULL) {
if ($op == 'logout') {
$apps = fb_connect_enabled_apps();
foreach ($apps as $fb_app) {
try {
$fb = fb_api_init($fb_app, FB_FBU_CURRENT);
if ($fb && $fb->api_client->session_key) {
// Log out of facebook
$session_key = $fb->api_client->session_key;
// http://forum.developers.facebook.com/viewtopic.php?id=21879
// Use next parameter to expire session.
drupal_goto("http://www.facebook.com/logout.php?app_key={$fb_app->apikey}&session_key={$session_key}&next=" . url("fb/connect/expire/{$fb_app->apikey}", NULL, NULL, TRUE));
}
} catch (Exception $e) {
fb_log_exception($e, t('Failed to log out of fbConnect session'));
}
}
}
}
Dave Cohen
committed
/**
* Allows other modules to specify which Facebook Connect features are
* required. This will affect how the FB_RequireFeatures javascript method is
* called.
*/
function fb_connect_require_feature($feature = NULL, $fb_app = NULL) {
if ($feature && !isset($fb_app))
$fb_app = $GLOBALS['fb_app'];
// some features may apply without an app, but for now let's enforce that an app is required.
if ($feature && !$fb_app)
return;
Dave Cohen
committed
static $features;
if (!$features)
$features = array();
if ($fb_app && !$features[$fb_app->apikey])
$features[$fb_app->apikey] = array('fb_app' => $fb_app,
'features' => array());
Dave Cohen
committed
if ($feature)
$features[$fb_app->apikey]['features'][$feature] = $feature;
Dave Cohen
committed
return $features;
}
/**
* Include facebook javascript in the footer of the current page.
*/
function fb_connect_footer($is_front) {
// Do nothing on FBML pages
if (function_exists('fb_canvas_is_fbml') && fb_canvas_is_fbml())
return;
Dave Cohen
committed
global $base_path;
$feature_data = fb_connect_require_feature();
if (count($feature_data)) {
foreach ($feature_data as $data) {
$fb_app = $data['fb_app'];
$features = $data['features'];
// drupal_add_js cannot add external javascript, so we use hook_footer instead.
$output = '<script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"></script>';
$output .= "\n";
$feature_list = '["' . implode('","', $features) . '"]';
// Put together the URL for the receiver. The prefix must be identical to the apps callback URL.
$receiver = fb_get_callback_url($fb_app) . "fb/connect/receiver";
$output .= "
Dave Cohen
committed
<script type=\"text/javascript\">
$(document).ready(function() {
FB_RequireFeatures({$feature_list}, function () {
//FB.FBDebug.logLevel = 4;
//FB.FBDebug.isEnabled = true;
Dave Cohen
committed
FB.Facebook.init(\"{$fb_app->apikey}\", \"{$receiver}\");
Dave Cohen
committed
});
});
</script>\n";
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
}
// Call function which only work after FB.Facebook.init has been called.
$output .= "
<script type=\"text/javascript\">
$(document).ready(fb_connect_init);
</script>\n";
}
return $output;
}
function fb_connect_block($op = 'list', $delta = 0, $edit = array()) {
if ($op == 'list') {
$items = array();
foreach (fb_connect_enabled_apps() as $fb_app) {
$d = 'login_' . $fb_app->label;
$items[$d] = array(
'info' => t('Facebook Connect Login to !app',
array('!app' => $fb_app->title)),
);
}
return $items;
}
else if ($op == 'configure') {
// TODO
}
else if ($op == 'save') {
// TODO
}
else if ($op == 'view') {
if (strpos($delta, 'login_') === 0) {
// Login block
$label = substr($delta, 6); // length of 'login_'
$fb_app = fb_get_app(array('label' => $label));
$fbu = fb_connect_already_loggedin($fb_app);
$fb = fb_connect_app_init($fb_app);
fb_connect_require_feature('XFBML', $fb_app);
$base = drupal_get_path('module', 'fb_connect');
drupal_add_js(array('fb_connect' => array(
'fbu' => $fbu ? $fbu : 0,
'logout_url' => url('logout'),
'enable_login' => TRUE,
),
), 'setting');
drupal_add_js($base . '/fb_connect.js');
// TODO: make content and login-button configurable
if ($fbu) {
$content = "You're connected, <fb:name uid=$fbu useyou=false></fb:user>.
<fb:profile-pic uid=$fbu></fb:profile_pic>
<fb:login-button onclick='fb_connect_logout_onclick();' autologoutlink=true></fb:login-button>";
} else {
$content = "This button should allow you to log in with your facebook credentials.
<fb:login-button onclick='fb_connect_login_onclick();'></fb:login-button>";
}
$block = array(
'subject' => t('Login via Facebook'),
'content' => $content,
);
return $block;