4 * Makes development with Drupal for Facebook much easier. Keep this
5 * module enabled until you're confident your app works perfectly.
7 * Produces warning messages and log messages
8 * when it detects something is wrong with
11 * Runs tests for Drupal's status page.
15 define('FB_DEVEL_URL_LINTER', 'http://developers.facebook.com/tools/lint');
17 function fb_devel_menu() {
18 $items['fb/devel'] = array(
19 'page callback' => 'fb_devel_page',
20 'type' => MENU_CALLBACK
,
21 'access callback' => TRUE
, /* TODO: restrict access */
24 $items['fb/devel/fbu'] = array(
25 'page callback' => 'fb_devel_fbu_page',
26 'type' => MENU_CALLBACK
,
27 'access callback' => TRUE
,
30 $items['fb/devel/tab'] = array(
31 'page callback' => 'fb_devel_tab',
32 'type' => MENU_CALLBACK
,
33 'access callback' => TRUE
, /* TODO: restrict access */
36 // Return some info for debugging AHAH problems
37 $items['fb/devel/js'] = array(
38 'page callback' => 'fb_devel_js',
39 'type' => MENU_CALLBACK
,
40 'access callback' => TRUE
,
43 $items['fb/devel/linter'] = array(
44 'title' => 'Facebook linter',
45 'page callback' => 'drupal_not_found', // Because we alter link, below.
46 'type' => MENU_NORMAL_ITEM
,
47 'access arguments' => array('access devel information'),
48 'menu_name' => 'devel',
49 'options' => array('alter' => TRUE
),
55 // Trick learned from devel.module, to make link to linter for the current page.
56 function fb_devel_translated_menu_link_alter(&$item) {
57 if ($item['link_path'] == 'fb/devel/linter' ||
58 $item['link_path'] == FB_DEVEL_URL_LINTER
) {
59 //dpm($item, __FUNCTION__);
60 $item['href'] = FB_DEVEL_URL_LINTER
; // href matters. link_path and router path do not.
61 $item['localized_options']['query'] = array(
62 'url' => url(request_path(), array('absolute' => TRUE
)),
68 * Implements hook_init().
70 function fb_devel_init() {
71 if (user_access('access devel information')) {
72 // Add our module's javascript.
73 drupal_add_js(drupal_get_path('module', 'fb_devel') .
'/fb_devel.js');
74 drupal_add_js(array('fb_devel' => array('verbose' => fb_verbose())), 'setting');
77 // fb_settings.inc sanity check.
78 if (isset($GLOBALS['fb_init_no_settings'])) {
79 if (user_access('access administration pages') && (module_exists('fb_canvas') || module_exists('fb_tab'))) {
80 // fb_settings.php must be included for canvas or tab support.
81 drupal_set_message(t('!drupal_for_facebook (fb_canvas.module) has been enabled, but fb_settings.inc is not included in settings.php. Please read the !readme.',
82 array('!drupal_for_facebook' => l(t('Drupal for Facebook'), 'http://drupal.org/project/fb'),
83 // This link should work with clean URLs
85 '!readme' => '<a href=' .
base_path() .
drupal_get_path('module', 'fb') .
'/README.txt>README.txt</a>')), 'error');
91 // $conf['fb_apikey'] sanity check.
92 if ($apikey = variable_get(FB_VAR_APIKEY
, NULL
)) {
93 $fb_app = fb_get_app(array('apikey' => $apikey));
94 $message = t('Drupal for Facebook no longer uses the \'fb_apikey\' variable. Change $conf[\'fb_apikey\'] in your settings.php. Use $conf[\'fb_id\'] instead, and make the value the app id (%app_id) instead of the apikey.', array(
95 '%app_id' => $fb_app->id
,
97 if (user_access(FB_PERM_ADMINISTER
)) {
98 drupal_set_message($message, 'error');
100 watchdog('fb_devel', $message, array(), WATCHDOG_WARNING
);
103 // $conf['fb_id'] sanity check
104 if ($id = variable_get(FB_VAR_ID
, NULL
)) {
105 if ($label = variable_get(FB_CONNECT_VAR_PRIMARY
, NULL
)) {
106 $fb_app = fb_get_app(array('label' => $label));
107 if ($fb_app && ($fb_app->id
!= $id)) {
108 $message = t('Drupal for Facebook has detected a problem. $conf[\'fb_id\'] (%fb_id) is not the same as the primary application %label (%fb_primary_id).',
111 '%fb_primary_id' => $fb_app->id
,
112 '%label' => $fb_app->label
,
114 if (user_access(FB_PERM_ADMINISTER
)) {
115 drupal_set_message($message, 'error');
117 watchdog('fb_devel', $message, array(), WATCHDOG_WARNING
);
122 // fb_user table sanity check
123 if (module_exists('fb_user')) {
124 if (db_query("SELECT count(*) FROM {authmap} WHERE module='fb_user'")->fetchField()) {
125 $message = 'fb_user data has not been migrated from authmap table. Run update.php.';
127 if (user_access('access administration pages')) {
128 drupal_set_message(t($message, $args), 'error');
130 watchdog('fb_devel', $message, $args, WATCHDOG_ERROR
);
134 // Old url rewrite sanity check.
135 if ($id = fb_settings(FB_SETTINGS_CB
)) {
136 if ($GLOBALS['_fb_app']->id
!= $id && $GLOBALS['_fb_app']->apikey
== $id) {
137 $message = 'Facebook callback URLs have changed. They now include the app\'s ID, instead of APIKEY. Your application %label has not been updated. Either <a target=_top href=!sync_url>sync properties</a> or manually change callbacks on remote settings.';
139 '%label' => $GLOBALS['_fb_app']->title
,
140 '!sync_url' => url(FB_PATH_ADMIN_APPS .
'/' .
$GLOBALS['_fb_app']->label .
'/fb/set_props', array(
141 'fb_url_alter' => FALSE
,
144 if (user_access('access administration pages')) {
145 drupal_set_message(t($message, $args), 'warning');
147 watchdog('fb_devel', $message, $args, WATCHDOG_WARNING
);
153 * Implements hook_fb().
155 function fb_devel_fb($op, $data, &$return) {
156 $fb_app = isset($data['fb_app']) ?
$data['fb_app'] : NULL
;
157 $fb = isset($data['fb']) ?
$data['fb'] : NULL
;
160 if ($op == FB_OP_INITIALIZE
) {
162 if (fb_settings(FB_SETTINGS_APIKEY
) &&
163 ($fb_app->apikey
!= fb_settings(FB_SETTINGS_APIKEY
))) {
164 $message = t('Drupal for Facebook has detected a problem. The initialized app has an apikey (%fb_app_apikey), while the settings indicates a different apikey (%fb_settings_apikey).', array(
165 '%fb_app_apikey' => $fb_app->apikey
,
166 '%fb_settings_apikey' => fb_settings(FB_SETTINGS_APIKEY
),
168 drupal_set_message($message, 'error');
169 watchdog('fb_devel', $message, array(), WATCHDOG_WARNING
);
173 // This value comes from url rewriting. Recommended on canvas pages.
174 $id = fb_settings(FB_SETTINGS_CB
);
177 if ($id && $id != $fb_app->id
) {
178 $message = t('fb_app id (%fb_app_id) does not equal fb settings id (%fb_settings_id). This is usually caused by the wrong callback url on your <a href="!url">facebook application settings form</a>.',
179 array('%fb_app_id' => $fb_app->id
,
180 '%fb_settings_id' => $id,
181 '!url' => "http://www.facebook.com/developers/apps.php",
183 drupal_set_message($message, 'warning');
184 watchdog('fb_devel', $message, array(), WATCHDOG_WARNING
);
188 // Catch badly formed links ASAP.
189 if ($id && !fb_is_canvas() && !fb_is_tab()) {
190 // Skip check on callbacks from facebook.
191 if ((arg(0) != 'fb_app') || (arg(1) != 'event')) {
192 $message = t('URL starts with %prefix. This should never happen on connect pages. Did the previous page have a badly formed link?', array(
193 '%prefix' => FB_SETTINGS_CB .
'/' .
$id,
195 drupal_set_message($message, 'error');
200 // path replacement sanity check
202 if ($base_path == "/{$fb_app->canvas}/") {
203 $message = t('Facebook canvas page matches Drupal base_path (%base_path). This is currently not supported.',
204 array('%base_path' => $base_path));
205 drupal_set_message($message, 'error');
206 watchdog('fb_devel', $message);
209 // Old API Sanity check.
210 if (isset($_REQUEST['fb_sig'])) {
211 $message = t('Passed old-style fb_sig parameters. Go to !url, edit your application. Under "migrations" enable "new sdks".', array(
212 '!url' => 'http://www.facebook.com/developers/apps.php',
215 watchdog('fb_devel', $message);
218 // server URL sanity check
219 // This is an expensive test, because it invokes api_client.
221 $props = $fb->api(array(
222 'method' => 'admin.getAppProperties',
223 'access_token' => fb_get_token($fb),
224 'properties' => array('connect_url', 'callback_url'),
226 $props = json_decode($props, TRUE
);
227 if (is_array($props)) {
228 // Strip "http(s):" to avoid warnings when the only difference is http vs https
229 $baseurl = str_replace(array('http://','https://'), '', $GLOBALS['base_url']);
230 foreach ($props as
$prop => $url) {
231 if ($url && (strpos($url, $baseurl) === FALSE
)) {
232 $message = t('The Facebook Application labeled %label has a suspicious %prop. The value is %value, while something starting with %url was expected. Consider editing !applink.', array(
233 '%label' => $fb_app->label
,
236 '%url' => $GLOBALS['base_url'],
237 '!applink' => l($fb_app->label
, FB_PATH_ADMIN_APPS .
'/' .
$fb_app->label
),
240 if (user_access('access administration pages')) {
241 drupal_set_message($message, 'warning');
243 watchdog('fb_devel', $message);
248 catch (Exception
$e) {
249 dpm($e, __FUNCTION__
);
250 if ($e->getCode() == 102) {
251 // Session key invalid or no longer valid 102, which we can ignore.
254 fb_log_exception($e, t('Failed to get app properties for %name.', array('%name' => $fb_app->title
)));
258 // App data sanity checks.
259 $fb_app_data = fb_get_app_data($fb_app);
261 // Account mapping format has changed!
262 if (isset($fb_app_data['fb_user']) && !is_array($fb_app_data['fb_user']['map_account'])) {
263 $message = 'The options for mapping facebook account to local accounts has changed. You must manually <a href=!url>edit your application</a>. Look for the map accounts options under facebook user settings.';
264 $args = array('!url' => url(FB_PATH_ADMIN_APPS .
'/' .
$fb_app->label
));
265 if (user_access('access administration pages')) {
266 drupal_set_message(t($message, $args), 'error');
268 watchdog('fb_devel', $message, $args, WATCHDOG_ERROR
);
273 elseif ($op == FB_APP_OP_EVENT
) {
274 $type = $data['event_type'];
275 // Facebook has notified us of some event.
276 $message = t('Facebook has notified the %label application of a %type event.',
277 array('%label' => $fb_app->label
,
279 $message .
= '<pre>' .
print_r($data, 1);
280 $message .
= print_r($_REQUEST, 1) .
'</pre>';
281 watchdog('fb_devel', $message);
284 elseif ($op == FB_OP_JS
) {
286 //$return[] = "debugger; // added by fb_devel.module";
289 elseif ($op == FB_OP_POST_INIT
) {
290 if (isset($_SESSION['fb_devel'])) {
291 // Counter helps track how long session has been around.
292 $_SESSION['fb_devel']['FB_OP_POST_INIT'] = $_SESSION['fb_devel']['FB_OP_POST_INIT'] + 1;
295 $_SESSION['fb_devel']['FB_OP_POST_INIT'] = 1;
298 // Javascript to help us with sanity checks.
301 'session_id' => session_id(),
302 'session_name' => session_name(),
306 elseif ($op == FB_OP_AJAX_EVENT
) {
307 if (fb_verbose() == 'extreme' && FALSE
) { // disabled to prevent console not defined error.
308 $session_id = session_id();
309 $session_name = session_name();
310 $return[] = "console.log('fb_devel.module extreme verbosity: original session_id is ' + Drupal.settings.fb_devel.session_name + ':' + Drupal.settings.fb_devel.session_id + ', session_id during FB_OP_AJAX_EVENT is $session_name:$session_id');";
311 $fbu = fb_facebook_user($data['fb']);
312 $return[] = "console.log('fb_facebook_user() during FB_OP_AJAX_EVENT is $fbu, data[event_data][fbu] is {$data[event_data][fbu]}');";
313 $return[] = "console.log('_COOKIE[fbu_{$fb_app->apikey}] is " .
$_COOKIE['fbu_' .
$fb_app->apikey
] .
"');";
314 $return[] = "FB_JS.reload();";
321 * Implements hook_footer().
323 function fb_devel_footerXXX($is_front) {
324 $output = "<!-- fb_devel_footer() -->\n";
325 $output .
= "<script type=\"text/javascript\">\n";
326 $output .
= "<!--//--><![CDATA[//><!--\n";
327 $output .
= " jQuery(document).bind('fb_init', FB_Devel.initHandler);\n";
328 //$output .= " FB_Devel.sanityCheck()\n";
329 $output .
= "\n//--><!]]>\n";
330 $output .
= "\n</script>\n";
337 * Provides a page with useful debug info.
339 * @TODO - clean this up and rely less on drupal_set_message() and dpm().
341 function fb_devel_page() {
342 global $_fb, $_fb_app;
345 if (isset($_REQUEST['require_login']) && $_REQUEST['require_login'])
346 fb_require_authorization($_fb);
350 $items['fb_settings'] = fb_settings();
354 $items['$GLOBALS[_fb]'] = $_fb;
356 // TODO: determine whether connect page or canvas.
358 drupal_set_message(t("session name: " .
session_name()));
359 drupal_set_message(t("session id: " .
session_id()));
360 drupal_set_message(t("cookie domain: " .
fb_settings(FB_SETTINGS_COOKIE_DOMAIN
)));
362 if (isset($_COOKIE['fbs_' .
$_fb_app->apikey
]))
363 drupal_set_message(t("fbs_" .
$_fb_app->apikey .
": " .
$_COOKIE["fbs_" .
$_fb_app->apikey
]));
365 drupal_set_message(t("<a href=\"!url\">processed link</a>, <a href=!url>unprocessed</a>", array('!url' => url('fb/devel'))));
366 drupal_set_message(t("getUser() returns " .
$_fb->getUser()));
367 drupal_set_message(t("getAccessToken() returns " .
$_fb->getAccessToken()));
369 drupal_set_message(t("base_url: " .
$GLOBALS['base_url']));
370 drupal_set_message(t("base_path: " .
$GLOBALS['base_path']));
371 drupal_set_message(t("url() returns: " .
url()));
374 if ($fbu = fb_get_fbu($user)) {
375 $path = "fb/devel/fbu/$fbu";
376 drupal_set_message(t("Learn more about the current user at !link",
377 array('!link' => l($path, $path))));
380 dpm(fb_get_fbu($user), 'Facebook user via fb_get_fbu');
381 //dpm($user, "Local user " . theme('username', $user));
383 if (isset($GLOBALS['fb_connect_apikey'])) {
384 drupal_set_message(t("fb_connect_apikey = " .
$GLOBALS['fb_connect_apikey']));
387 dpm(fb_settings(), 'fb_settings()');
388 dpm($_COOKIE, 'cookie');
389 dpm($_REQUEST, "Request");
390 //dpm($_fb_app, "fb_app");
391 dpm($_SESSION, "session:");
393 foreach ($items as
$key => $val) {
394 if (is_array($val) || is_object($val)) {
395 $markup = print_r($val, 1);
401 '#prefix' => "<dl><dt>$key</dt><dd><pre>",
402 '#suffix' => "</pre></dd></dl>",
403 '#markup' => $markup,
412 * Provides a profile tab (FBML) with useful debug info.
415 function fb_devel_tab() {
416 global $_fb, $_fb_app;
419 $info['session_id'] = session_id();
420 $info['session_name'] = session_name();
421 $info['cookie domain'] = fb_settings(FB_SETTINGS_COOKIE_DOMAIN
);
424 $link_test = url(current_path(), array('absolute' => TRUE
));
425 $info['link test'] = "<a href=\"$link_test\">link test (processed)</a>";
426 $info['link test 2'] = "<a href='$link_test'>link test (not processed)</a>";
428 //$info['fb_app'] = $_fb_app;
429 //$info['fb'] = $_fb;
430 $info['fb_settings'] = fb_settings();
431 $info['REQUEST'] = $_REQUEST;
432 $info['SESSION'] = $_SESSION;
433 $info['COOKIE'] = $_COOKIE;
436 $info['fb->getSignedRequest()'] = $_fb->getSignedRequest();
437 $fbu = fb_facebook_user();
439 $info["fb->api(/$fbu)"] = $_fb->api('/' .
$fbu);
441 catch (Exception
$e) {
442 $info["fb->api(/$fbu)"] = $e->getMessage();
445 if ($app_id = $_REQUEST['fb_sig_app_id']) {
447 $info['fb->api(fb_sig_app_id)'] = $_fb->api($_REQUEST['fb_sig_app_id']);
449 catch (Exception
$e) {
450 $info['fb->api(fb_sig_app_id)'] = $e->getMessage();
455 print '<p>fb_devel.module tab</p>';
456 foreach ($info as
$key => $value) {
458 if (is_array($value)) {
459 print '<pre>' .
check_plain(print_r($value, 1)) .
'</pre>';
461 elseif (is_object($value)) {
462 print '<pre>' .
check_plain(print_r($value, 1)) .
'</pre>';
465 print '<pre>' .
$value .
'</pre>';
474 * A page which tests function which work with facebook user ids
476 function fb_devel_fbu_page($fbu = NULL
) {
477 global $_fb, $_fb_app;
480 $info = fb_users_getInfo(array($fbu), $_fb);
481 $output = "<p>Debug FQL info about facebook id $fbu ({$info[0]['name']}):</p>\n";
482 $output .
= "<img src=http://graph.facebook.com/$fbu/picture></img>";
483 $output .
= "<pre>" .
print_r($info[0], 1) .
"</pre>";
486 $info = $_fb->api($fbu, array('metadata' => 1));
487 $output .
= "<p>Debug info about facebook id $fbu ({$info['name']}):</p>\n";
488 $output .
= "<img src=http://graph.facebook.com/$fbu/picture></img>";
489 $output .
= "<pre>" .
print_r($info, 1) .
"</pre>";
491 foreach (array('statuses') as
$connection) {
493 if ($data = $_fb->api($fbu .
'/' .
$connection)) {
494 $output .
= "<p>$connection<pre>";
495 $output .
= print_r($data, 1);
496 $output .
= "</pre></p>\n\n";
499 catch (FacebookApiException
$e) {
500 fb_log_exception($e, t('Failed to lookup %connection', array('%connection' => $fbu .
'/' .
$connection)));
504 $friends = $_fb->api($fbu .
'/friends');
505 //dpm($friends, "$fbu/friends returned");
507 foreach ($friends['data'] as
$data) {
508 $items[] = l($data['name'], "fb/devel/fbu/{$data['id']}");
511 $output .
= "\n<p>Known friends:<ul><li>";
512 $output .
= implode("</li>\n <li>", $items);
513 $output .
= "</li></ul></p>\n\n";
516 catch (FacebookApiException
$e) {
517 fb_log_exception($e, t('Failed to lookup friends of facebook user %fbu', array('%fbu' => $fbu)));
520 if (module_exists('fb_user')) {
521 $local_friends = fb_user_get_local_friends($fbu);
524 foreach ($local_friends as
$uid) {
525 $account = user_load($uid);
526 $items[] = theme('username', $account);
529 $output .
= "\n<p>Local friends:<ul><li>";
530 $output .
= implode("</li>\n <li>", $items);
531 $output .
= "</li></ul></p>\n\n";
536 drupal_set_message(t("You have to specify a facebook user id."), 'error');
542 * Provide some information for testing AHAH and AJAX scenarios.
544 function fb_devel_js() {
547 $data .
= "session_name() = " .
session_name() .
"\n";
548 $data .
= "session_id() = " .
session_id() .
"\n";
549 $data .
= "REQUEST: " .
dprint_r($_REQUEST, 1) .
"\n";
550 $data .
= "SESSION: " .
dprint_r($_SESSION, 1) .
"\n";
553 print drupal_json_output(array('status' => TRUE
, 'data' => $data));
557 function fb_devel_block_info() {
558 // Provide two copies of same block, for iframe scenarios.
559 $items[0]['info'] = t('Facebook Devel Page Info');
560 $items[1]['info'] = t('Facebook Devel Page Info 2');
564 function fb_devel_block_view($delta = '') {
565 if (user_access('access devel information')) {
567 'subject' => t('Facebook Devel Info'),
568 'content' => drupal_get_form('fb_devel_info'),
573 function fb_devel_info() {
574 global $_fb, $_fb_app;
582 if (fb_settings(FB_SETTINGS_TYPE
) == FB_SETTINGS_TYPE_CANVAS
) {
583 $info['Page Status'] = t('Serving canvas page.');
585 elseif (fb_settings(FB_SETTINGS_TYPE
) == FB_SETTINGS_TYPE_CONNECT
) {
586 $info['Page Status'] = t('Connected via Facebook Connect');
588 elseif (fb_settings(FB_SETTINGS_TYPE
) == FB_SETTINGS_TYPE_PROFILE
) {
589 $info['Page Status'] = t('Serving deprecated FBML profile tab');
591 elseif (fb_settings(FB_SETTINGS_TYPE
) == FB_SETTINGS_TYPE_PAGE_TAB
) {
592 $info['Page Status'] = t('Iframe tab on page %page', array(
593 '%page' => fb_settings(FB_SETTINGS_PAGE_ID
),
596 elseif (!fb_settings(FB_SETTINGS_TYPE
)) {
597 $info['Page Status'] = t('Facebook PHP SDK initialized.'); // Either a facebook connect page, or canvas page where user has not authorized app.
600 $info['Page Status'] = t('Global fb instance is set, but page type unknown (%type).',
601 array('%type' => fb_settings(FB_SETTINGS_TYPE
),
604 $fbu = fb_facebook_user();
605 $info['fb_facebook_user'] = $fbu;
608 $info['login button'] = theme('fb_login_button', array('text' => 'Connect'));
609 $info['login link'] = "<a href=# onclick='FB.login(function(response) {alert(\"FB.login() success.\");}, {perms:Drupal.settings.fb.perms}); return false;'>fb login</a>";
612 // Tests for link on canvas pages (iframe cookie test)
613 //$link_test = url(fb_scrub_urls($_REQUEST['q']), array('absolute' => TRUE));
614 //$info['link test'] = "<a href=\"$link_test\">link test (processed)</a>";
615 //$info['link test 2'] = "<a href='$link_test'>link test (not processed)</a>";
617 if ($fbu && FALSE
) { // Disabled as this expensive check can cause problems.
618 if (!fb_api_check_session($_fb)) {
619 $info['fb_api_check_session()'] = t('Returned FALSE');
622 $info['fb_api_check_session()'] = t('Returned TRUE');
627 $info['Page Status'] = t('Not a canvas page.');
629 // Use theme_username() rather than theme('username') because we want link to local user, even when FBML is enabled
636 $info['local user'] = theme_username(array('account' => $user,
637 'attributes_array' => array(),
640 $info['fb_get_fbu'] = fb_get_fbu($user->uid
);
641 $info['base_url'] = $base_url;
642 $info['base_path'] = $base_path;
643 $info['url() returns'] = url();
644 $info['current_path'] = current_path();
645 $info['arg(0) is'] = arg(0);
646 $info['arg(1) is'] = arg(1);
647 $info['session_id'] = session_id();
648 $info['session_name'] = session_name();
649 $info['fb_settings()'] = fb_settings();
650 $info['request'] = $_REQUEST;
651 $info['user'] = $GLOBALS['user'];
652 $info['fb_app'] = $_fb_app;
653 $info['session'] = $_SESSION;
654 $info['cookies'] = $_COOKIE;
658 $info['signed_request'] = $_fb->getSignedRequest();
661 $token = fb_get_token($_fb);
662 $props = $_fb->api(array(
663 'method' => 'admin.getAppProperties',
664 'properties' => 'about_url', 'application_name',
665 'access_token' => $token,
667 $info['application properties'] = $props;
670 catch (FacebookApiException
$e) {
671 fb_log_exception($e, "failed to get app properties");
673 // $info["fb->getSession()"] = $_fb->getSession();
674 $info["fb->getSignedRequest()"] = $_fb->getSignedRequest();
677 $info["fb->api($fbu)"] = $_fb->api($fbu, array(
678 'access_token' => fb_get_token($_fb),
681 catch (FacebookApiException
$e) {
682 if (fb_verbose() == 'extreme') {
683 // After oauth upgrade, this exception is thrown always, when using app token.
684 // So only show error when fb_verbose is extreme. Hopefully facebook will fix the issue.
685 fb_log_exception($e, "failed to look up _fb->api($fbu)."); // Dont show token, it can inlude app secret. using token " . fb_get_token($_fb));
692 foreach ($info as
$key => $val) {
693 if (is_string($val) || is_numeric($val) || !$val) {
694 $form[$key] = array('#markup' => t($key) .
' = ' .
$val,
695 '#weight' => count($form),
696 '#suffix' => '<br/>',
702 '#type' => 'fieldset',
704 '#collapsible' => TRUE
,
705 '#collapsed' => TRUE
,
706 '#weight' => count($form),
711 '#markup' => dprint_r($val, 1)),
719 * Implements hook_user_view().
721 function fb_devel_user_view($account, $view_mode, $langcod) {
722 if (user_access('administer users') && user_access('access devel information')) {
723 $account->content
['fb_devel'] = array(
724 '#type' => 'fieldset',
725 '#title' => t('Drupal for Facebook Devel'),
726 '#description' => t('Information from facebook API, visible only to administrators.'),
727 '#collapsible' => TRUE
,
728 '#collapsed' => TRUE
,
732 foreach (fb_get_all_apps() as
$fb_app) {
733 $account->content
['fb_devel'][$fb_app->label
] = array(
734 '#type' => 'fieldset',
735 '#title' => $fb_app->title
,
737 if ($fbu = fb_get_fbu($account, $fb_app)) {
738 $fb = fb_api_init($fb_app);
740 // Don't use fb_api() because we don't want the caching here.
741 $info = $fb->api("/$fbu", array('access_token' => fb_get_token($fb)));
743 //$info = fb_users_getInfo(array($fbu), $fb, TRUE);
744 $account->content
['fb_devel'][$fb_app->label
]['info'] = array(
746 '#markup' => "facebook graph for /$fbu:" .
dprint_r($info, 1),
749 if ($token = fb_get_token($fb, $fbu)) {
750 $account->content
['fb_devel'][$fb_app->label
]['token'] = array(
752 '#markup' => 'access_token: ' .
fb_get_token($fb, $fbu),
753 '#prefix' => '<p>', '#suffix' => '</p>',
756 $account->content
['fb_devel'][$fb_app->label
]['graph'] = array(
758 '#markup' => l(t('Browse graph as this user'), 'https://graph.facebook.com/' .
$fbu .
'?metadata=1&access_token=' .
$token),
759 '#prefix' => '<p>', '#suffix' => '</p>',
763 catch (Exception
$e) {
764 $account->content
['fb_devel'][$fb_app->label
]['#description'] = $e->getMessage();
765 $account->content
['fb_devel'][$fb_app->label
]['info'] = array(
766 '#type' => 'fieldset',
767 '#title' => t('Failed to get info for !app.',
768 array('!app' => $fb_app->title
)),
769 '#collapsible' => TRUE
,
770 '#collapsed' => TRUE
,
771 'exception' => array(
773 '#markup' => dprint_r($e, 1),
779 $account->content
['fb_devel'][$fb_app->label
]['info'] = array(
781 '#markup' => t('No mapping to a facebook account.'),
789 * Implements hook_cron().
791 * Remove obsolete data from {users} table. Not a serious problem,
792 * just cruft in the database which should never have been saved.
795 function fb_devel_cron() {
797 $result = db_query_range('SELECT * FROM {users} WHERE data LIKE :as OR data like :iau OR data like :fbu',
798 0, $limit, array(':as' => '%\"app_specific\"%',
799 ':iau' => '%\"is_app_user\"%',
800 ':fbu' => '%\"fbu\"%'));
802 foreach ($result as
$account) {
803 $data = unserialize($account->data
);
804 // Clean out the bogus data.
805 foreach (array('app_specific', 'username', 'fbu', 'info') as
$key) {
809 ->fields(array('data' => serialize($data), 'uid' => $account->uid
))
813 db_query("UPDATE {users} SET data=:data WHERE uid=:uid",
814 serialize($data), $account->uid);
817 print(t('Cleaned up data for user %name (%uid), it is now: !data',
818 array('%name' => $account->name
,
819 '%uid' => $account->uid
,
820 '!data' => '<pre>' .
print_r($data, 1) .
'</pre>',
827 function fb_devel_fb_tab($op, $data, &$return) {
829 if (fb_verbose() === 'extreme') {
830 $return['fb_devel'] = array(
832 '#markup' => __FUNCTION__ .
':' .
print_r($data, 1),
833 '#prefix' => '<pre>',
834 '#suffix' => '</pre>',
837 if ($data['profile_id'] && isset($data['fb'])) {
838 $return['fb_devel']['profile_id'] = array(
840 '#markup' => __FUNCTION__ .
':' .
print_r($data['fb']->api($data['profile_id']), 1),
841 '#prefix' => '<pre>',
842 '#suffix' => '</pre>',
851 * Wrapper for fb_fql_query(). Useful for debugging.
853 function fb_devel_fql_query($fb, $query, $params = array()) {
854 if (!is_object($fb)) {
855 dpm(debug_backtrace(), __FUNCTION__
);
858 $url_params = $params;
859 $url_params['query'] = $query;
860 $url_params['format'] = 'JSON';
861 $url = url("https://api.facebook.com/method/fql.query", array('query' => $url_params));
862 dpm(func_get_args(), __FUNCTION__
);
863 drupal_set_message(l($url, $url));
864 return fb_fql_query($fb, $query, $params);