'fb_connect_receiver', 'type' => MENU_CALLBACK, 'access callback' => TRUE, ); // Ajax helper $items['fb_connect/js'] = array( 'page callback' => 'fb_connect_js_cb', 'type' => MENU_CALLBACK, 'access callback' => TRUE, ); // Session and authmap helpers. $items[FB_CONNECT_PATH_SESSION_START] = array( 'page callback' => 'fb_connect_session_start_cb', 'type' => MENU_CALLBACK, 'access callback' => TRUE, ); $items[FB_CONNECT_PATH_SESSION_END] = array( 'page callback' => 'fb_connect_session_end_cb', 'type' => MENU_CALLBACK, 'access callback' => TRUE, ); // Admin pages $items[FB_PATH_ADMIN . '/fb_connect'] = array( 'title' => 'Facebook Connect', 'description' => 'Configure Facebook Connect', 'page callback' => 'drupal_get_form', 'page arguments' => array('fb_connect_admin_settings'), 'access arguments' => array(FB_PERM_ADMINISTER), 'file' => 'fb_connect.admin.inc', 'type' => MENU_LOCAL_TASK, ); return $items; } /** * Session start callback. * * This can be invoked when a user is logging into facebook connect. If the * user was previously logged into Drupal. An authmap entry will be made * linking the two accounts. */ function fb_connect_session_start_cb() { global $_fb, $_fb_app; global $user; if (fb_verbose() == 'extreme') { watchdog('fb_connect', t("fb_connect_session_start_cb, session_name is " . session_name() . ", session_id is " . session_id())); } //watchdog('fbc_authmap_cb', dprint_r($_REQUEST, 1)); // debug if ($_fb_app->apikey == $_REQUEST['apikey']) { // http://wiki.developers.facebook.com/index.php/Verifying_The_Signature if ($fbu = $_fb->get_loggedin_user()) { if (function_exists('_fb_user_set_authmap')) { _fb_user_set_authmap($_fb_app, $fbu, $user); } } } session_destroy(); // Destroy local drupal session, not session controlled by facebook cookies. $user = drupal_anonymous_user(); drupal_json(TRUE); exit(); } function fb_connect_session_end_cb() { global $user; if (fb_verbose() == 'extreme') { watchdog('fb_connect', t("fb_connect_session_end_cb, session_name is " . session_name() . ", session_id is " . session_id())); } session_destroy(); // When user logs out of connect, give them a new session. $user = drupal_anonymous_user(); drupal_json(TRUE); exit(); } /** * Ajax javascript callback. * * For sites which use ajax, various events may create javascript which is * normally embedded in a page. For example, posting to a user's wall. When * ajax is used instead of a page reload, this callback will provide any * javascript which should be run. */ function fb_connect_js_cb() { $extra = fb_invoke(FB_OP_CONNECT_JS_INIT, NULL, array()); $extra_js = implode("\n", $extra); print $extra_js; exit(); } /** * 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. * * Supports SSL, http://wiki.developers.facebook.com/index.php/Facebook_Connect_Via_SSL. */ function fb_connect_receiver() { // DEPRECATED and will go away! // facebook_config global comes from facebook's API. $src_suffix = $GLOBALS['facebook_config']['debug'] ? '.debug' : '' ; $src = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? "https://ssl.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver$src_suffix.js" : "http://static.ak.connect.facebook.com/js/api_lib/v0.4/XdCommReceiver$src_suffix.js" ; $output = << HTML; print $output; die(); // prevent Drupal from writing anything else. } /** * 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) { if (isset($GLOBALS['_fb_app']) && fb_is_iframe_canvas() && $GLOBALS['_fb_app']->apikey != $fb_app->apikey) { // If we're in an iframe, only support connect for the iframe app. return; } if ($fb = fb_api_init($fb_app, FB_FBU_CURRENT)) { $fbu = $fb->get_loggedin_user(); // TODO: sometimes this method indicates we are logged in when we really are not. Find a way to verify. if ($fbu && (!isset($GLOBALS['_fb_app']) || $GLOBALS['_fb_app']->apikey != $fb_app->apikey)) { // 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)); } // Remember which app we've initialized. _fb_connect_set_app($fb_app); } return $fb; } /** * Helper function for other modules to know page is connected. * * Note that this may return data on connect pages and in iframe apps * (depending on how iframe is configured). */ function fb_connect_get_app() { return _fb_connect_set_app(); } function _fb_connect_set_app($fb_app = NULL) { static $cache; if (isset($fb_app)) { $cache = $fb_app; } return $cache; } /** * 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; } /** * Implementation of hook_fb(). */ function fb_connect_fb($op, $data, &$return) { //dpm(func_get_args(), "fb_connect_fb($op)"); if ($op == FB_OP_CURRENT_APP && !$return) { // This will cause fb.module to set the global $_fb when user is logged in via fbConnect. if ($label = variable_get(FB_CONNECT_VAR_PRIMARY, NULL)) { $return = fb_get_app(array('label' => $label)); } } elseif ($op == FB_OP_POST_INIT) { if ($label = variable_get(FB_CONNECT_VAR_PRIMARY, NULL)) { if ($data['fb_app']->label == $label && !fb_is_fbml_canvas()) { $fb_app = $data['fb_app']; // Init Facebook javascript for primary app fb_connect_require_feature('XFBML', $fb_app); // fb_connect_init_option('reloadIfSessionStateChanged', TRUE, $fb_app); fb_connect_init_option('ifUserConnected', "{FB_Connect.on_connected}", $fb_app); fb_connect_init_option('ifUserNotConnected', "{FB_Connect.on_not_connected}", $fb_app); } } // Include our admin hooks. if (fb_is_fb_admin_page()) { module_load_include('inc', 'fb_connect', 'fb_connect.admin'); } } elseif ($op == FB_OP_CONNECT_JS_INIT) { foreach (fb_connect_init_js() as $js) { $return[] = $js; } } } /** * This wrapper function around drupal_add_js() ensures that our * settings are added once and only once when needed. */ function _fb_connect_add_js() { static $just_once; if (!isset($just_once)) { if ($uid = $GLOBALS['user']->uid && module_exists('fb_user')) { $session_start_url = url(FB_CONNECT_PATH_SESSION_START); } drupal_add_js(array( 'fb_connect' => array( 'front_url' => url(''), 'fbu' => fb_facebook_user(), 'uid' => $uid, 'in_iframe' => fb_is_iframe_canvas(), 'session_start_url' => $session_start_url, 'session_end_url' => url(FB_CONNECT_PATH_SESSION_END), ), ), 'setting'); drupal_add_js(drupal_get_path('module', 'fb_connect') . '/fb_connect.js'); $just_once = TRUE; } } /** * 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') { // Affect connect pages, but not canvas pages. if (fb_is_fbml_canvas() || fb_is_iframe_canvas()) return; $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; // Figure out where to send the user. if ($_REQUEST['destination']) { $next = url($_REQUEST['destination'], array('absolute' => TRUE)); // It pains me to muck with $_REQUEST['destination'], but facebook's weak-ass API leaves us little choice. unset($_REQUEST['destination']); } else { $next = url('', array('absolute' => TRUE)); } // 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=" . $next); } } catch (Exception $e) { fb_log_exception($e, t('Failed to log out of fbConnect session')); } } } } /** * Here we attempt to log the user out of facebook connect, not just Drupal. * If we fail, the user will be reconnected right away, because * connect cookies are still in place. */ function fb_connect_exit($url = NULL) { if (isset($GLOBALS['fb_connect_logging_out'])) { global $_fb; session_write_close(); // drupal_goto calls this, so why not us? if (!isset($url)) $url = url('', NULL, NULL, TRUE); $_fb->logout($url); } } /** * 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) && isset($GLOBALS['_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 && !isset($fb_app)) return; static $features; if (!$features) { _fb_connect_add_js(); // include our javascript. $features = array(); } if ($fb_app && !isset($features[$fb_app->apikey])) $features[$fb_app->apikey] = array( 'fb_app' => $fb_app, 'features' => array()); if ($feature) $features[$fb_app->apikey]['features'][$feature] = $feature; return $features; } /** * Add an option when initializing facebook's javascript api. */ function fb_connect_init_option($option = NULL, $value = NULL, $fb_app = NULL) { if ($option && !isset($fb_app)) $fb_app = $GLOBALS['_fb_app']; if ($option && !$fb_app) return; static $options; if (!$options) $options = array(); if ($fb_app && !isset($options[$fb_app->apikey])) { $options[$fb_app->apikey] = array(); } if ($option) $options[$fb_app->apikey][$option] = $value; return $options; } /** * Add javascript to a facebook connect page. * * Use this to add calls to facebook JS, * http://wiki.developers.facebook.com/index.php/JS_API_Index. * * We use Drupal's cache to store the javascript until it is rendered * to a page. This approach is analogous to drupal_set_message * storing data temporarily in the session. We use cache instead of * session, because the session is not shared between Facebook's event * callbacks and regular page requests. * */ function fb_connect_init_js($js = NULL) { $fbu = fb_facebook_user(); $fb_app = $GLOBALS['_fb_app']; $cid = 'fb_connect_init_js_' . $fb_app->apikey . '_' . $fbu; $cache = cache_get($cid, 'cache'); if (!isset($cache->data)) { $cache = new stdClass(); $cache->data = array(); } if ($js) { $cache->data[] = $js; cache_set($cid, $cache->data, 'cache', time() + 60000); // Update cache } elseif ($js === NULL) { cache_clear_all($cid, 'cache'); } return $cache->data; } /** * Include facebook javascript in the footer of the current page. */ function fb_connect_footer($is_front) { // Do nothing on FBML pages if (fb_is_fbml_canvas()) { return; } global $base_path; $fb_feature_src = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? "https://ssl.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" : "http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" ; $feature_data = fb_connect_require_feature(); $option_data = fb_connect_init_option(); if (count($feature_data)) { foreach ($feature_data as $data) { // Give other modules a chance to add javascript which executes after init. $extra = fb_invoke(FB_OP_CONNECT_JS_INIT, $data, array()); $extra_js = implode("\n", $extra); $fb_app = $data['fb_app']; $features = $data['features']; $options = json_encode($option_data[$fb_app->apikey]); // Hack! What's the way to json_encode a function name? $options = str_replace('"{', '', $options); $options = str_replace('}"', '', $options); // drupal_add_js cannot add external javascript, so we use hook_footer instead. $output = ''; $output .= "\n"; $feature_list = '["' . implode('","', $features) . '"]'; // Put together the URL for the receiver. The prefix must be identical to the apps connect URL. //$receiver = fb_connect_get_connect_url($fb_app) . "fb_connect/receiver"; // OLD WAY. XXX $receiver = variable_get('fb_xd_receiver', url(drupal_get_path('module', 'fb') . '/fb_receiver.html', array('absolute' => TRUE))); $output .= " \n"; } } return $output; } /** * Convenience method to get an apps connect URL. * */ function fb_connect_get_connect_url($fb_app) { // absolute URL with no rewriting applied global $base_url; return $base_url . '/'; } function _fb_connect_block_login_defaults() { return array('anon_not_connected' => array( 'title' => t('Facebook Connect'), 'body' => t('Connect with Facebook'), ), 'user_not_connected' => array( 'title' => t('Facebook Connect'), 'body' => t('Connect with Facebook'), ), 'connected' => array( 'title' => t('Facebook Connect'), 'body' => "", ), ); } /** * Implementation of hook_block. */ 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; } elseif ($op == 'configure') { $orig_defaults = _fb_connect_block_login_defaults(); $defaults = variable_get('fb_connect_block_' . $delta, $orig_defaults); $form['config'] = array('#tree' => TRUE); // Settings for each user status that we can detect. foreach (array('anon_not_connected', 'user_not_connected', 'connected') as $key) { $form['config'][$key] = array( '#type' => 'fieldset', // title and description below '#collapsible' => TRUE, '#collapsed' => FALSE, ); $form['config'][$key]['title'] = array( '#type' => 'textfield', '#title' => t('Default title'), //'#description' => t('Default title.'), '#default_value' => $defaults[$key]['title'], ); $form['config'][$key]['body'] = array( '#type' => 'textarea', '#title' => t('Body'), //'#description' => t('Block body'), '#default_value' => $defaults[$key]['body'], ); } $form['config']['anon_not_connected']['#title'] = t('Anonymous user, not connected'); $form['config']['anon_not_connected']['#description'] = t('Settings when local user is Anonymous, and not connected to Facebook. Typically a new account will be created when the user clicks the connect button.'); $form['config']['anon_not_connected']['body']['#description'] = t('Suggestion: %default .', array('%default' => $orig_defaults['anon_not_connected']['body'])); $form['config']['user_not_connected']['#title'] = t('Registered user, not connected'); $form['config']['user_not_connected']['#description'] = t('Settings when local user is registered, and not connected to Facebook. Typically the facebook id will be linked to the local id after the user clicks the connect button.'); $form['config']['user_not_connected']['body']['#description'] = t('Suggestion: %default .', array('%default' => $orig_defaults['user_not_connected']['body'])); $form['config']['connected']['#title'] = t('Connected user'); $form['config']['connected']['#description'] = t('Settings when local user is connected to Facebook. You may render facebook\'s logout button, and/or information about the user. Consider using XFBML such as <fb:name uid=!fbu></fb:name> or <fb:profile-pic uid=!fbu></fb:profile-pic>', array('xfbml_url' => 'http://wiki.developers.facebook.com/index.php/XFBML')); $form['config']['connected']['body']['#description'] .= t('Note that !fbu will be replaced with the user\'s facebook id.
Suggestion: %default .', array('%default' => $orig_defaults['connected']['body'])); $form['config']['format'] = filter_form($defaults['format']); $form['config']['format']['#description'] .= t('

Be sure to select a format which allows XFBML tags! (That is, use Full HTML or PHP code, rather than Filtered HTML.)

Format selected will apply to all body fields above.

'); $form['config']['format']['#collapsed'] = FALSE; return $form; } elseif ($op == 'save') { $edit['config']['format'] = $edit['format']; variable_set('fb_connect_block_' . $delta, $edit['config']); } elseif ($op == 'view') { if (strpos($delta, 'login_') === 0) { // Login block $label = substr($delta, 6); // length of 'login_' $fb_app = fb_get_app(array('label' => $label)); if ($fb = fb_connect_app_init($fb_app)) { $fbu = $fb->get_loggedin_user(); fb_connect_require_feature('XFBML', $fb_app); fb_connect_init_option('ifUserConnected', "{FB_Connect.on_connected}", $fb_app); fb_connect_init_option('ifUserNotConnected', "{FB_Connect.on_not_connected}", $fb_app); $base = drupal_get_path('module', 'fb_connect'); $defaults = variable_get('fb_connect_block_' . $delta, _fb_connect_block_login_defaults()); if ($fbu) { $subject = $defaults['connected']['title']; $content = $defaults['connected']['body']; // substitute %fbu $content = str_replace('!fbu', $fbu, $content); } elseif ($GLOBALS['user']->uid > 1) { $subject = $defaults['user_not_connected']['title']; $content = $defaults['user_not_connected']['body']; } elseif ($GLOBALS['user']->uid == 1) { $subject = $defaults['user_not_connected']['title']; $content = '' . t('Facebook Connect login disabled for user #1.') . ''; } else { $subject = $defaults['anon_not_connected']['title']; $content = $defaults['anon_not_connected']['body']; } // If user has changed defaults, run filter if (isset($defaults['format'])) { $subject = check_plain($subject); $content = check_markup($content, $defaults['format'], FALSE); } $block = array( 'subject' => $subject, 'content' => $content, ); return $block; } } } } function fb_connect_form_alter(&$form, &$form_state, $form_id) { // Add our settings to the fb_app edit form. if (isset($form['fb_app_data'])) { $fb_app = $form['#fb_app']; $fb_app_data = fb_get_app_data($fb_app); $fb_connect_data = $fb_app_data['fb_connect']; $form['fb_app_data']['fb_connect'] = array( '#type' => 'fieldset', '#title' => 'Facebook Connect', '#tree' => TRUE, '#collapsible' => TRUE, '#collapsed' => $node->label ? TRUE : FALSE, ); // "Primary" will be initialized on every non-canvas page. $primary_label = variable_get(FB_CONNECT_VAR_PRIMARY, NULL); $form['fb_app_data']['fb_connect']['primary'] = array( '#type' => 'checkbox', '#title' => t('Primary'), '#description' => t('Initialize fbConnect javascript on all (non-canvas) pages. If this site supports multiple Facebook Apps, this may be checked for at most one.'), '#default_value' => isset($fb_app->label) && ($primary_label == $fb_app->label), ); if (($primary_label) && ($primary_label != $fb_app->label)) { $form['fb_app_data']['fb_connect']['primary']['#description'] .= '
' . t('Note that checking this will replace %app as the primary Facebook Connect app.', array('%app' => $primary_label)); } $form['#submit'][] = 'fb_connect_app_submit'; } // Add button to login form. if (($form_id == 'user_login_block' || $form_id == 'user_login') && !fb_is_fbml_canvas()) { if ($app_label = variable_get(FB_CONNECT_VAR_LOGIN, NULL)) { $fb_app = fb_get_app(array('label' => $app_label)); // Render connect link if not connected already. if ($fb = fb_connect_app_init($fb_app) && !fb_facebook_user($fb)) { // Ensure that facebook javascript is in the page closure. fb_connect_require_feature('XFBML', $fb_app); fb_connect_init_option('ifUserConnected', "{FB_Connect.on_connected}", $fb_app); fb_connect_init_option('ifUserNotConnected', "{FB_Connect.on_not_connected}", $fb_app); // Add button to the form. // @TODO - make markup customizable. $form['fb_connect_button'] = array( '#type' => 'markup', '#value' => 'Connect with Facebook', '#prefix' => '
', '#suffix' => '
', '#weight' => 4, // LOG IN button weight is 2. ); } } if ($form_id == 'user_login') { // On login, we must leave the user/login page or else get access denied. drupal_add_js(array('fb_connect' => array('destination' => url('user'))), 'setting'); } } } function fb_connect_app_submit($form, &$form_state) { $values = $form_state['values']; $label = $values['label']; $data = $values['fb_app_data']['fb_connect']; if ($data['primary']) { variable_set(FB_CONNECT_VAR_PRIMARY, $label); drupal_set_message(t('%label is the primary Facebook Connect application.', array('%label' => $label))); } elseif ($label == variable_get(FB_CONNECT_VAR_PRIMARY, NULL)) { // This app was the primary one, but the user has unchecked it. variable_set(FB_CONNECT_VAR_PRIMARY, NULL); } } /** * Implementation of hook_theme_registry_alter(). * * Override theme functions for things that can be displayed using * XFBML. Currently overriding username and user_picture. We rename * the original entries, as we will use them for users without * javascript enabled. * * This hook is not well documented. Who knows what its supposed to * return? No doubt this will need updating with each new version of * Drupal. */ function fb_connect_theme_registry_alter(&$theme_registry) { // Ideally, we'd do this only on themes which will certainly be used for facebook connect pages. if (variable_get(FB_CONNECT_VAR_THEME_USERNAME_2, TRUE) || (variable_get(FB_CONNECT_VAR_THEME_USERNAME_1, TRUE) && $theme_registry['username']['type'] == 'module')) { // Re-register the original theme function under a new name. $theme_registry['fb_connect_username_orig'] = $theme_registry['username']; // Override theme username $theme_registry['username'] = array( 'arguments' => array('object' => NULL), 'function' => 'fb_connect_theme_username_override', 'type' => 'module', ); } if (variable_get(FB_CONNECT_VAR_THEME_USERPIC_2, TRUE) || (variable_get(FB_CONNECT_VAR_THEME_USERPIC_1, TRUE) && $theme_registry['user_picture']['type'] == 'module')) { // Re-register the original theme function under a new name. $theme_registry['fb_connect_user_picture_orig'] = $theme_registry['user_picture']; // Override theme username $theme_registry['user_picture'] = array( 'arguments' => array('account' => NULL), 'function' => 'fb_connect_theme_user_picture_override', 'type' => 'module', ); } } /** * Our replacement for theme('user_picture', ...) */ function fb_connect_theme_user_picture_override($account) { // Markup without fb_connect. $orig = theme('fb_connect_user_picture_orig', $account); // Make no changes to FBML pages. if (fb_is_fbml_canvas()) { return $orig; } // Respect Drupal's profile pic, if uploaded. if (isset($account->picture) && $account->picture) { return $orig; } if ($fbu = fb_get_object_fbu($account)) { $output = theme('fb_connect_fbml_user_picture', $fbu, $account, $orig); } else { $output = $orig; } return $output; } /** * Our replacement for theme('username', ...) */ function fb_connect_theme_username_override($object) { $orig = theme('fb_connect_username_orig', $object); // Make no changes to FBML pages. if (fb_is_fbml_canvas()) { return $orig; } elseif ($fbu = fb_get_object_fbu($object)) { // Theme the username with XFBML, using original username as backup. return theme('fb_connect_fbml_username', $fbu, $object, $orig); } else { return $orig; } } /** * Implements hook_theme(). * * We use theme function for XFBML username and picture so that the * markup can be relatively easily customized. */ function fb_connect_theme() { return array( 'fb_connect_fbml_username' => array( 'arguments' => array( 'fbu' => NULL, 'object' => NULL, 'orig' => NULL, ), ), 'fb_connect_fbml_user_picture' => array( 'arguments' => array( 'fbu' => NULL, 'account' => NULL, 'orig' => NULL, ), ), 'fb_connect_fbml_popup' => array( 'arguments' => array('elements' => NULL), ), ); } function theme_fb_connect_fbml_username($fbu, $object, $orig) { if (!$fbu) { return $orig; } $wrap_pre = "$orig\n"; if ($object->uid && user_access('access user profiles')) { // Provide link if local account. $wrap_pre = $wrap_pre . ''; $wrap_post = '' . $wrap_post; $ifcantsee = 'ifcantsee="' . addslashes(check_plain($object->name)) . '"'; } $fbml = ""; $output = $wrap_pre . $fbml . $wrap_post; return $output; } function theme_fb_connect_fbml_user_picture($fbu, $object, $orig) { if (!$fbu) return $orig; $fbml = ""; $wrap_pre = '' . $orig . ''; if ($object->uid && user_access('access user profiles')) { // Provide link to local account. $wrap_pre = $wrap_pre . ''; $wrap_post = '' . $wrap_post; } return $wrap_pre . $fbml . $wrap_post; } function theme_fb_connect_fbml_popup($elem) { // Hide this markup until javascript shows it. $t = '\n"; return $t; }