? facebook-platform ? themes/ep_fbml Index: README.txt =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/README.txt,v retrieving revision 1.16 diff -u -p -r1.16 README.txt --- README.txt 5 Feb 2009 02:47:28 -0000 1.16 +++ README.txt 22 Feb 2009 21:49:05 -0000 @@ -5,7 +5,7 @@ More information: http://www.drupalforfa Primary author and maintainer: Dave Cohen (http://www.dave-cohen.com/contact) -Version: HEAD (version 2.x for Drupal 5.x) +Version: N/A (version 2.x for Drupal 6.x) Please read http://drupal.org/node/288721#version and confirm that you are using the correct version. Index: fb.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb.info,v retrieving revision 1.2 diff -u -p -r1.2 fb.info --- fb.info 5 Feb 2009 03:34:50 -0000 1.2 +++ fb.info 22 Feb 2009 21:49:05 -0000 @@ -1,3 +1,5 @@ name = DFF Facebook API description = Imports and uses the Facebook API. package = Drupal for Facebook +core = 6.x +php = 5 Index: fb.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb.install,v retrieving revision 1.2 diff -u -p -r1.2 fb.install --- fb.install 7 Apr 2008 20:56:49 -0000 1.2 +++ fb.install 22 Feb 2009 21:49:05 -0000 @@ -7,18 +7,8 @@ function _fb_install_set_weight() { function fb_install() { _fb_install_set_weight(); } -function fb_update_1() { - _fb_install_set_weight(); -} -/** - * The callback URL has changed and this requires manual updates to App settings. - */ -function fb_update_2() { - $message = t('Warning! The Drupal for Facebook modules have changed. Manual intervention is required! See !url1 or !url2.', - array('!url1' => l('http://apps.facebook.com/drupalforfacebook/node/1055', 'http://apps.facebook.com/drupalforfacebook/node/1055'), - '!url2' => l('http://drupalforfacebook.org/node/1055','http://drupalforfacebook.org/node/1055'))); - drupal_set_message($message); - watchdog('fb', $message); +function fb_uninstall() { + _fb_install_set_weight(); } -?> \ No newline at end of file + Index: fb.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb.module,v retrieving revision 1.40 diff -u -p -r1.40 fb.module --- fb.module 5 Feb 2009 02:47:28 -0000 1.40 +++ fb.module 22 Feb 2009 21:49:05 -0000 @@ -67,7 +67,7 @@ function fb_init() { if (strpos($key, 'fb_') === 0) $req[] = $key . '=' . $val; } - $url = url($_REQUEST['q'], implode('&', $req), NULL, TRUE); + $url = url($_REQUEST['q'], array('query' => $req, 'absolute' => TRUE)); if (fb_verbose()) watchdog('fb_debug', t('Facebook session key was %old, now %new. Destroying session and sending user to %url.', array('%old' => $_SESSION['fb_frame_params']['session_key'], @@ -93,7 +93,7 @@ function fb_init() { array('!drupal_for_facebook' => l(t('Drupal for Facebook'), 'http://drupal.org/project/fb'), // This link should work with clean URLs // disabled. - '!readme' => 'README.txt')), 'error'); + '!readme' => 'README.txt')), 'error'); } // Ask other modules for app detail @@ -186,18 +186,21 @@ function fb_api_init($fb_app, $fbu) { $fbu_orig = $fbu; // Determine the actual facebook user id to use. - if ($GLOBALS['fb'] && $GLOBALS['fb']->validate_fb_params() && + if ($GLOBALS['fb'] && $GLOBALS['fb']->api_key == $fb_app->apikey && + $GLOBALS['fb']->validate_fb_params() && ($fbu == FB_FBU_CURRENT || $fbu == FB_FBU_ANY || $fbu == $GLOBALS['fb']->get_loggedin_user())) { return $GLOBALS['fb']; } - else if (($fbu == FB_FBU_CURRENT || $fbu == FB_FBU_ANY) + else if ($GLOBALS['fb']->api_key == $fb_app->apikey && + ($fbu == FB_FBU_CURRENT || $fbu == FB_FBU_ANY) && isset($_SESSION['fb_frame_params']) && !$_REQUEST['fb_sig']) { $params = $_SESSION['fb_frame_params']; $fbu = $params['user']; $session = $params['session_key']; } - else if ($fbu == FB_FBU_CURRENT && $GLOBALS['fb']) { + else if ($GLOBALS['fb'] && $GLOBALS['fb']->api_key == $fb_app->apikey && + $fbu == FB_FBU_CURRENT) { // No current user to use, probably anonymous canvas page. return $GLOBALS['fb']; } @@ -258,9 +261,9 @@ function fb_api_init($fb_app, $fbu) { if ($fbu_orig != FB_FBU_NO_SESSION && $fbu_orig != FB_FBU_CURRENT && !$fb->get_loggedin_user()) { // An FBU other than CURRENT was specified, but we failed to log in. - watchdog('fb', t('Failed to log into facebook app %app as user %user', - array('%app' => $fb_app->title, - '%user' => $fbu_orig)), WATCHDOG_ERROR); + watchdog('fb', 'Failed to log into facebook app %app as user %user', + array('%app' => $fb_app->title, + '%user' => $fbu_orig), WATCHDOG_ERROR); } } @@ -315,6 +318,18 @@ function fb_facebook_user($fb = NULL) { } /** + * Facebook provides a method, users_isAppUser(), which is buggy and + * unreliable. So we need to implement our own. + */ +function fb_is_app_user($fb) { + if ($fb->api_client->added || $fb->api_client->is_user) + return TRUE; + else + return $fb->api_client->users_isAppUser; +} + + +/** * Given a local user id, find the facebook id. */ function fb_get_fbu($uid, $fb_app = NULL) { @@ -342,7 +357,7 @@ function fb_get_fbu($uid, $fb_app = NULL * TODO: This code will probably not handle every case and may need some work. */ function fb_get_callback_url($fb_app) { - $url = url('', NULL, NULL, TRUE) . FB_SETTINGS_APP_NID . '/'. $fb_app->nid . '/'; + $url = url('', array('absolute' => TRUE)) . FB_SETTINGS_APP_NID . '/'. $fb_app->nid . '/'; return $url; } @@ -362,7 +377,7 @@ function fb_get_app($search_data) { * Convenience method to return a list of all known apps, suitable for form * elements. */ -function fb_get_app_options($include_current) { +function fb_get_app_options($include_current = FALSE) { $apps = fb_get_all_apps(); $options = array(); if ($include_current) @@ -471,15 +486,15 @@ function fb_user_load($fbu = NULL) { if (!$account) $account = user_load(array('uid' => variable_get('fb_facebook_user', 2))); if (!$account) - watchdog('fb', t('Failed to load user from facebook fbu=%fbu', - array('%fbu' => $fbu)), 'error'); + watchdog('fb', 'Failed to load user from facebook fbu=%fbu', + array('%fbu' => $fbu), 'error'); $account->fbu = $fbu; return $account; } } -function fb_form_alter($form_id, &$form) { +function fb_form_alter(&$form, &$form_state, $form_id) { // Because facebook users don't have email, it can't be required on user form if ($form_id == 'user_register') { if (user_access('administer users')) { @@ -494,26 +509,21 @@ function fb_form_alter($form_id, &$form) } -function fb_menu($may_cache) { +function fb_menu() { $items = array(); - if (!$may_cache) { - // Initialization moved to fb_init(), nothing to do here. - } - else { // When forms are submitted directly to us, we cache the results, // and show them later via this callback - $items[] = array('path' => 'fb/form_cache', - 'callback' => '_fb_form_cache_cb', + $items['fb/form_cache'] = array( + 'page callback' => '_fb_form_cache_cb', 'type' => MENU_CALLBACK, - 'access' => TRUE); + 'access callback' => TRUE); // A page to help determine infinite session keys - $items[] = array('path' => 'fb/session', - 'callback' => '_fb_session_cb', + $items['fb/session'] = array( + 'page callback' => '_fb_session_cb', 'type' => MENU_CALLBACK, - 'access' => TRUE); // TODO: restrict access? - } + 'access callback' => TRUE); // TODO: restrict access? return $items; } @@ -753,14 +763,14 @@ function fb_add_js($filename, $type) { static $cache; if (!$cache) { $cache = array(); - + // Add the most basic file we need. $base_file = drupal_get_path('module', 'fb') . '/fb_fbml.js'; $base_file .= "?v=".filemtime($base_file); drupal_add_js($base_file, 'module', 'fbml'); // Add some settings that FBJS code will often need. - $baseUrl = url('', NULL, NULL, TRUE); + $baseUrl = url('', array('absolute' => TRUE)); drupal_add_js(array('fbjs' => array('baseUrlFb' => $baseUrl, 'baseUrl' => fb_scrub_urls($baseUrl), ), @@ -788,4 +798,4 @@ function fb_verbose() { return variable_get('fb_verbose', NULL); } -?> \ No newline at end of file +?> Index: fb_app.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_app.info,v retrieving revision 1.2 diff -u -p -r1.2 fb_app.info --- fb_app.info 5 Feb 2009 03:34:50 -0000 1.2 +++ fb_app.info 22 Feb 2009 21:49:05 -0000 @@ -1,5 +1,6 @@ name = DFF Applications description = Allows Drupal to host Facebook Applications package = Drupal for Facebook -dependencies = fb +dependencies[] = fb +core = 6.x Index: fb_app.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_app.install,v retrieving revision 1.6 diff -u -p -r1.6 fb_app.install --- fb_app.install 5 Aug 2008 20:27:30 -0000 1.6 +++ fb_app.install 22 Feb 2009 21:49:05 -0000 @@ -6,36 +6,62 @@ */ // TODO: some of these tables should be created by othe module install files. +/** + * hook_install() + */ function fb_app_install() { - switch ($GLOBALS['db_type']) { - case 'mysql': - case 'mysqli': - db_query(" -CREATE TABLE IF NOT EXISTS {fb_app} ( -nid int(11) unsigned NOT NULL, -label varchar(128) NOT NULL, -apikey varchar(128) NOT NULL, -id varchar(128) NOT NULL, -secret varchar(128) NOT NULL, -canvas varchar(128) NOT NULL, -require_login int(4) NOT NULL, -create_account int(4) NOT NULL, -unique_account int(4) NOT NULL, -data longtext, -PRIMARY KEY (nid), -UNIQUE KEY (apikey) -) /*!40100 DEFAULT CHARACTER SET UTF8 */; -"); - - } - - drupal_set_message(t('Facebook Application module installed. Please grant yourself permissions and then browse to Create Content => Facebook Application to get started.', array('!perm' => url('admin/user/access'), '!create' => url('node/add/fb-app')))); + // Create tables. + drupal_install_schema('fb_app'); + drupal_set_message(t('Facebook Application module installed. Please grant yourself permissions and then browse to Create Content => Facebook Application to get started.', array('!perm' => url('admin/user/permissions'), '!create' => url('node/add/fb-app')))); } -function fb_app_update_1() { - // Add id field - $ret[] = update_sql('ALTER TABLE {fb_app} ADD id varchar(128) NOT NULL'); - return $ret; +/** + * hook_uninstall() + */ +function fb_app_uninstall() { + // Remove tables. + drupal_uninstall_schema('fb_app'); +} + +function fb_app_schema() { + $schema['fb_app'] = array( + 'description' => 'Main FB_APP table', + 'fields' => array( + 'nid' => array('type' => 'int', 'length' => 11, 'unsigned' => TRUE, 'not null' => TRUE, ), + 'label' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, ), + 'apikey' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, ), + 'id' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, ), + 'secret' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, ), + 'canvas' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, ), + 'require_login' => array('type' => 'int', 'length' => 4, 'not null' => TRUE, ), + 'create_account' => array('type' => 'int', 'length' => 4, 'not null' => TRUE, ), + 'unique_account' => array('type' => 'int', 'length' => 4, 'not null' => TRUE, ), + 'rid' => array('type' => 'int', 'length' => 10, 'unsigned' => TRUE, 'not null' => TRUE, ), + 'data' => array('type' => 'text', 'size' => 'big', ), + ), + 'unique keys' => array( + 'apikey' => array('apikey'), + ), + 'primary key' => array('nid'), + ); + $schema['fb_app_block'] = array( + 'fields' => array( + 'nid' => array('type' => 'int', 'length' => 11, 'unsigned' => TRUE, 'not null' => TRUE, ), + 'delta' => array('type' => 'varchar', 'length' => 32, 'not null' => TRUE, ), + 'format' => array('type' => 'int', 'length' => 11, 'default' => 0, ), + 'body' => array('type' => 'text', 'size' => 'big', 'not null' => TRUE, ), + ), + 'primary key' => array('nid', 'delta'), + ); + $schema['fb_cache_filter'] = drupal_get_schema_unprocessed('system', 'cache'); + + return $schema; } -?> \ No newline at end of file + +function fb_app_update_6100() { + // Add id field + $ret = array(); + db_add_field($ret, 'fb_app', 'id', array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, )); + return $ret; +} \ No newline at end of file Index: fb_app.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_app.module,v retrieving revision 1.22 diff -u -p -r1.22 fb_app.module --- fb_app.module 8 Feb 2009 20:41:35 -0000 1.22 +++ fb_app.module 22 Feb 2009 21:49:05 -0000 @@ -79,18 +79,26 @@ function fb_app_fb($op, $data, &$return) } /** - * hook_menu + * Loader callback for drupal menu api. */ -function fb_app_menu($may_cache) { +function fb_app_nid_load($nid) { + $node = node_load($nid); + if ($node->type == 'fb_app') { + return $node; + } +} + +/** + * Implementation of hook_menu(). + */ +function fb_app_menu() { $items = array(); - if ($may_cache) { - // Allow facebook to notify on various events, like adding or removing an app. - $items[] = array('path' => FB_APP_PATH_EVENT, - 'access' => TRUE, - 'callback' => 'fb_app_event_cb', - 'type' => MENU_CALLBACK, + // Allow facebook to notify on various events, like adding or removing an app. + $items[FB_APP_PATH_EVENT] = + array('access callback' => TRUE, + 'page callback' => 'fb_app_event_cb', + 'type' => MENU_CALLBACK, ); - } return $items; } @@ -122,15 +130,14 @@ function fb_app_node_info() { ); } -function fb_app_access($op, $node) { - global $user; - if (user_access('administer fb apps')) +function fb_app_access($op, $node, $account) { + if (user_access('administer fb apps', $account)) return TRUE; - if ($op == 'create' && user_access('create fb apps')) + if ($op == 'create' && user_access('create fb apps', $account)) return TRUE; else if ($op == 'update' || $op == 'delete') { if ($node->uid == $user->uid && - user_access('edit own fb apps')) + user_access('edit own fb apps', $account)) return TRUE; } } @@ -266,9 +273,24 @@ function fb_app_view($node, $teaser=FALS return $node; } +function fb_app_theme() { + return array( + 'fb_app' => array( + 'arguments' => array('data' => NULL), + ), + 'dl' => array( + 'arguments' => array('items' => NULL), + ), + 'fb_app_user_info' => array( + 'arguments' => array('fb_app' => NULL, 'info' => NULL), + ), + ); +} + function fb_app_get_about_url($fb_app) { if ($fb_app->id) - return url("http://www.facebook.com/apps/application.php", "id=$fb_app->id"); + return url("http://www.facebook.com/apps/application.php", + array('query' => array('id' => $fb_app->id))); } function theme_fb_app($fb_app) { @@ -283,7 +305,7 @@ function theme_fb_app($fb_app) { if ($fb_app->$key) $data[$name] = $fb_app->$key; } - $about_url = fb_app_get_about_url($data); + $output .= theme('dl', $data); return $output; } @@ -472,7 +494,7 @@ function fb_app_user($op, &$edit, &$acco function theme_fb_app_user_info($fb_app, $info) { if ($info['pic_big']) $output .= '

'; - $fb_link = l($info['name'], 'http://www.facebook.com/profile.php', NULL, 'id='.$info['uid']); + $fb_link = l($info['name'], 'http://www.facebook.com/profile.php', array('query' => 'id=' . $info['uid'])); if ($info['is_app_user']) $output .= '

' . t('!fb_link uses %title', array('!fb_link' => $fb_link, @@ -503,5 +525,4 @@ function fb_app_token_values($type = 'al } return $values; } - ?> \ No newline at end of file Index: fb_canvas.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_canvas.info,v retrieving revision 1.2 diff -u -p -r1.2 fb_canvas.info --- fb_canvas.info 5 Feb 2009 03:34:50 -0000 1.2 +++ fb_canvas.info 22 Feb 2009 21:49:05 -0000 @@ -1,5 +1,6 @@ name = DFF Canvas Pages description = Support for Facebook Canvas Pages. You will also need an FBML theme. package = Drupal for Facebook -dependencies = fb fb_app - +dependencies[] = fb +dependencies[] = fb_app +core = 6.x Index: fb_canvas.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_canvas.module,v retrieving revision 1.22 diff -u -p -r1.22 fb_canvas.module --- fb_canvas.module 5 Feb 2009 02:47:28 -0000 1.22 +++ fb_canvas.module 22 Feb 2009 21:49:05 -0000 @@ -7,13 +7,14 @@ * */ -function fb_canvas_menu($may_cache) { +function fb_canvas_menu() { $items = array(); if ($may_cache) { - $items[] = array('path' => 'fb/canvas/session', - 'callback' => 'fb_canvas_session_cb', - 'type' => MENU_CALLBACK, - 'access' => TRUE); + $items['fb/canvas/session'] = array( + 'page callback' => 'fb_canvas_session_cb', + 'type' => MENU_CALLBACK, + 'access callback' => TRUE, + ); } return $items; } @@ -51,7 +52,7 @@ function fb_canvas_block($op = 'list', $ } $_SESSION['fb_canvas_session'] = TRUE; - $url = url('fb/canvas/session', NULL, NULL, TRUE); + $url = url('fb/canvas/session', array('absolute' => TRUE)); return array('subject' => NULL, 'content' => ""); } @@ -76,17 +77,15 @@ function fb_canvas_fb($op, $data, &$retu else if (fb_canvas_is_iframe()) $custom_theme = $fb_canvas_data['theme_iframe']; - // This is for backward compatability (delete eventually) - if (!$custom_theme) - $custom_theme = variable_get('fb_theme', 'fb_fbml'); + if (fb_verbose() && FALSE) // Useful for debugging FBML errors + watchdog('fb_debug', "setting custom_theme to $custom_theme in fb_canvas_fb"); - // Special handling for forms, as they are submitted directly to us, not // to apps.facebook.com/canvas // we will buffer, and later cache, the results. if (fb_canvas_handling_form()) ob_start(); - + //drupal_set_message("fb_canvas_fb" . dpr($_GET, 1) . 'arg(0) = ' . dpr(arg(0), 1) . 'arg(1) = ' . dpr(arg(1), 1) . 'frontpage ' . dpr(variable_get('site_frontpage', 'node'), 1)); if ($_GET['q'] == drupal_get_normal_path(variable_get('site_frontpage', 'node'))) { if ($fb->get_loggedin_user()) { @@ -109,6 +108,7 @@ function fb_canvas_fb($op, $data, &$retu ob_end_clean(); if ($destination) { + watchdog('fb_debug', "FB_OP_EXIT, handling form, original destination: $destination"); // Fully qualified URLs need to be modified to point to facebook app. // URLs are fully qualified when a form submit handler returns a path, // or any call to drupal_goto. @@ -118,6 +118,7 @@ function fb_canvas_fb($op, $data, &$retu // canvas page, so we'll use Facebook's method. // Will this preempt other hook_exits? if ($fb) { + watchdog('fb_debug', "FB_OP_EXIT, handling form, redirecting to $destination"); $fb->redirect($destination); } } @@ -126,7 +127,7 @@ function fb_canvas_fb($op, $data, &$retu $token = uniqid('fb_'); $cid = session_id() . "_$token"; watchdog('fb', "Storing cached form page $cid, then redirecting"); - cache_set($cid, 'cache_page', $output, time() + (60 * 5), drupal_get_headers()); // (60 * 5) == 5 minutes + cache_set($cid, $output, 'cache_page', time() + (60 * 5), drupal_get_headers()); // (60 * 5) == 5 minutes $dest = 'http://apps.facebook.com/' . $fb_app->canvas . "/fb/form_cache/$cid"; // $fb->redirect($url); // Does not work! @@ -164,7 +165,7 @@ function fb_canvas_fb($op, $data, &$retu /** * Implementation of hook_form_alter. */ -function fb_canvas_form_alter($form_id, &$form) { +function fb_canvas_form_alter(&$form, &$form_state, $form_id) { // Add our settings to the fb_app edit form. if (is_array($form['fb_app_data'])) { $node = $form['#node']; @@ -205,31 +206,34 @@ function fb_canvas_form_alter($form_id, '#default_value' => $fb_canvas_data['front_added'], ); + /* XXX menu code here needs updating to D6 // Allow primary links to be different on facebook versus the rest of the // site. Code from menu_configure() in menu.module. - $root_menus = menu_get_root_menus(); - - $primary_options = $root_menus; - $primary_options[0] = t(''); - $secondary_options = $root_menus; - $secondary_options[0] = t(''); - - $form['fb_app_data']['fb_canvas']['primary_links'] = - array('#type' => 'select', - '#title' => t('Menu containing primary links'), - '#description' => t('Your application can have primary links different from those used elsewhere on your site.'), - '#default_value' => $fb_canvas_data['primary_links'], - '#options' => $primary_options, - ); - $form['fb_app_data']['fb_canvas']['secondary_links'] = - array('#type' => 'select', - '#title' => t('Menu containing secondary links'), - '#default_value' => $fb_canvas_data['secondary_links'], - '#options' => $secondary_options, - '#description' => t('If you select the same menu as primary links then secondary links will display the appropriate second level of your navigation hierarchy.'), + + $primary = variable_get('menu_primary_links_source', 'primary-links'); + $primary_options = array_merge($menu_options, array('' => t(''))); + $form['fb_app_data']['fb_canvas']['menu_primary_links_source'] = + array( + '#type' => 'select', + '#title' => t('Source for the primary links'), + '#default_value' => $fb_canvas_data['primary_links'], + '#options' => $primary_options, + '#tree' => FALSE, + '#description' => t('Your application can have primary links different from those used elsewhere on your site.'), ); - - + + $secondary_options = array_merge($menu_options, array('' => t(''))); + $form['fb_app_data']['fb_canvas']['menu_secondary_links_source'] = + array( + '#type' => 'select', + '#title' => t('Source for the secondary links'), + '#default_value' => $fb_canvas_data['secondary_links'], + '#options' => $secondary_options, + '#tree' => FALSE, + '#description' => t('If you select the same menu as primary links then secondary links will display the appropriate second level of your navigation hierarchy.'), + ); +*/ + // Override themes $themes = system_theme_data(); ksort($themes); @@ -282,6 +286,15 @@ function fb_canvas_form_alter($form_id, // We've stored #action_old and #action_new so custom modules have the option to change it back. } + // Drupal includes wacky markup for javascript junk in node forms. It + // makes things look terrible in FBML. It only works when javascript is + // enabled and it should have been implemented to degrade gracefully, but + // it wasn't. + if ($form['body_field']) { + unset($form['body_field']['teaser_js']); + unset($form['body_field']['teaser_include']); + } + } else if (fb_canvas_is_iframe()) { //dpm($form, 'fb_canvas_form_alter'); @@ -306,7 +319,7 @@ function fb_canvas_nodeapi(&$node, $op, $output = theme('dl', array(t('Canvas URL') => "http://apps.facebook.com/$fb_app->canvas", )); - + $node->content['fb_canvas'] = array('#value' => $output, '#weight' => 2); @@ -343,10 +356,13 @@ function fb_canvas_handling_form() { // This may need work function _fb_canvas_make_form_action_local($action) { + //dpm($action, "_fb_canvas_make_form_action_local"); + global $base_path; + // If action is fully qualified, do not change it if (strpos($action, ':')) return $action; - + // I'm not sure where the problem is, but sometimes actions have two question marks. I.e. // /htdocs/?app=foo&q=user/login?destination=comment/reply/1%2523comment-form // Here we replace 3rd (or more) '?' with '&'. @@ -356,8 +372,25 @@ function _fb_canvas_make_form_action_loc $action .= '&' . implode('&', $parts); } + $relative = url(''); + $absolute = url('', array('absolute'=>TRUE)); + global $fb_app; + + if (strpos($action, FB_SETTINGS_APP_NID)) { + $action = $absolute . substr($action, strlen($relative)); + } + else if (strpos($action, $relative) === 0) { + // Replace relative action with absolute. + // Include fb settings + // TODO: FB_SETTINGS_PAGE_TYPE + $action = $absolute . FB_SETTINGS_APP_NID . '/' . $fb_app->nid . '/' . substr($action, strlen($relative)); + } + + //dpm($action, '_fb_canvas_make_form_action_local returning'); + return $action; + //drupal_set_message("form action now " . "http://".$_SERVER['HTTP_HOST']. $action); // debug - return "http://".$_SERVER['HTTP_HOST']. $action; + //return "http://".$_SERVER['HTTP_HOST']. $action; } /** @@ -366,7 +399,7 @@ function _fb_canvas_make_form_action_loc function fb_canvas_goto($path) { global $fb, $fb_app; if ($fb && (fb_canvas_is_fbml() || fb_canvas_is_iframe())) { - $url = fb_canvas_fix_url(url($path, NULL, NULL, TRUE), $fb_app); + $url = fb_canvas_fix_url(url($path, array('absolute' => TRUE)), $fb_app); $fb->redirect($url); } else { @@ -384,9 +417,16 @@ function fb_canvas_goto($path) { function fb_canvas_fix_url($url, $fb_app) { global $base_url; + + $patterns[] = "|{$base_url}/" . FB_SETTINGS_APP_NID . "/{$fb_app->nid}/|"; // Here we assume apps.facebook.com. Is this safe? $replacements[] = "http://apps.facebook.com/{$fb_app->canvas}/"; + + // fully qualified paths + $patterns[] = "|".url('', array('absolute' => TRUE))."|"; + $replacements[] = "http://apps.facebook.com/{$fb_app->canvas}/"; + $patterns[] = "|fb_cb_type/[^/]*/|"; $replacements[] = ""; @@ -394,8 +434,12 @@ function fb_canvas_fix_url($url, $fb_app // Facebook will prepend "appNNN_" all our ids $patterns[] = "|#([^\?]*)|"; $replacements[] = "#app{$fb_app->id}_$1"; + + watchdog('fb_debug', "fb_canvas_fix_url($url), patterns: " . dprint_r($patterns, 1) . " replacements: " . dprint_r($replacements, 1)); $url = preg_replace($patterns, $replacements, $url); + watchdog('fb_debug', "fb_canvas_fix_url returning $url"); + return $url; } @@ -464,11 +508,19 @@ function fb_canvas_process($output, $add if ($fb) { $page_type = fb_settings(FB_SETTINGS_PAGE_TYPE); $nid = $fb_app->nid; - $base = url(); // short URL with rewrite applied. + $base_before_rewrite = ''; + $base = $base_path . fb_settings_url_rewrite_outbound($base_before_rewrite, NULL, NULL); // short URL with rewrite applied. if (fb_canvas_is_fbml()) { //dpm($output, "before fb_canvas_process"); // We're producing FBML for a canvas page + /* + TODO: $output['logo'] is not being processed properly by these + patterns. fb_canvas_process() returns '/sites/all/themes/fb_fbml/logo.png' + and Facebook complains "Relative URLs not allowed here" + + */ + // Change links to use canvas on Facebook // Links ending in #something: $patterns[] = "|=\"{$base}([^\"]*#)|"; @@ -535,6 +587,9 @@ function fb_canvas_process($output, $add } } if (count($patterns)) { + //dpm($patterns, "fb_canvas_process patterns"); + //dpm($replacements, "fb_canvas_process replacements"); + $return = preg_replace($patterns, $replacements, $output); @@ -574,4 +629,5 @@ function fb_canvas_process_fbml($output, else return $output; } + ?> \ No newline at end of file Index: fb_connect.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_connect.info,v retrieving revision 1.2 diff -u -p -r1.2 fb_connect.info --- fb_connect.info 5 Feb 2009 03:34:50 -0000 1.2 +++ fb_connect.info 22 Feb 2009 21:49:05 -0000 @@ -1,4 +1,6 @@ name = DFF Connect description = Login to Drupal with Facebook username and password, and other fbConnect features. You will need a fbConnect-aware theme. package = Drupal for Facebook -dependencies = fb fb_app +core = 6.x +dependencies[] = fb +dependencies[] = fb_app Index: fb_connect.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_connect.module,v retrieving revision 1.7 diff -u -p -r1.7 fb_connect.module --- fb_connect.module 10 Feb 2009 23:39:59 -0000 1.7 +++ fb_connect.module 22 Feb 2009 21:49:05 -0000 @@ -8,17 +8,14 @@ * Facebook Connect aware. */ -function fb_connect_menu($may_cache) { +function fb_connect_menu() { $items = array(); - if ($may_cache) { - $items[] = array( - 'path' => 'fb/connect/receiver', - 'callback' => 'fb_connect_receiver', - 'type' => MENU_CALLBACK, - 'access' => TRUE, - ); - } + $items['fb/connect/receiver'] = array( + 'page callback' => 'fb_connect_receiver', + 'type' => MENU_CALLBACK, + 'access callback' => TRUE, + ); return $items; } @@ -116,7 +113,7 @@ function fb_connect_user($op, &$edit, &$ $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('', NULL, NULL, TRUE)); + drupal_goto("http://www.facebook.com/logout.php?app_key={$fb_app->apikey}&session_key={$session_key}&next=" . url('', array('absolute' => TRUE))); } } catch (Exception $e) { fb_log_exception($e, t('Failed to log out of fbConnect session')); Index: fb_devel.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_devel.info,v retrieving revision 1.2 diff -u -p -r1.2 fb_devel.info --- fb_devel.info 5 Feb 2009 03:34:50 -0000 1.2 +++ fb_devel.info 22 Feb 2009 21:49:05 -0000 @@ -1,6 +1,9 @@ name = DFF Devel description = Blocks and messages that help when developing and debugging Apps. package = Drupal for Facebook -dependencies = fb devel +dependencies[] = fb +dependencies[] = devel +core = 6.x + Index: fb_devel.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_devel.module,v retrieving revision 1.11 diff -u -p -r1.11 fb_devel.module --- fb_devel.module 3 Feb 2009 22:54:42 -0000 1.11 +++ fb_devel.module 22 Feb 2009 21:49:05 -0000 @@ -1,20 +1,16 @@ 'fb/devel', - 'callback' => 'fb_devel_page', - 'type' => MENU_CALLBACK, - 'access' => TRUE, // TODO: restrict access - ); - $items[] = array('path' => 'fb/devel/fbu', - 'callback' => 'fb_devel_fbu_page', - 'type' => MENU_CALLBACK, - 'access' => TRUE, - ); - } +function fb_devel_menu() { + $items['fb/debug'] = array('page callback' => 'fb_devel_cb', + 'type' => MENU_CALLBACK, + 'access callback' => TRUE, /* TODO: restrict access */ + ); + + $items['fb/devel/fbu'] = array('page callback' => 'fb_devel_fbu_page', + 'type' => MENU_CALLBACK, + 'access' => TRUE, + ); + return $items; } @@ -33,7 +29,7 @@ function fb_devel_fb($op, $data, &$retur '!url' => "http://www.facebook.com/developers/apps.php", )); drupal_set_message($message, 'error'); - watchdog('fb_devel', $message); + watchdog('fb_devel', $message, array(), WATCHDOG_ERROR); } // Theme sanity check @@ -45,7 +41,7 @@ function fb_devel_fb($op, $data, &$retur // disabled. '!readme' => 'README.txt')); drupal_set_message($message, 'error'); - watchdog('fb_devel', $message); + watchdog('fb_devel', $message, array(), WATCHDOG_ERROR); } // path replacement sanity check @@ -68,7 +64,10 @@ function fb_devel_fb($op, $data, &$retur $message .= dprint_r($_REQUEST,1); watchdog('fb_devel', $message); } - + + else if ($op == FB_OP_CANVAS_EXIT && $data['fb'] && $return) { + watchdog('fb_devel', t('Drupal is redirecting a canvas page, destination is %destination.', array('%destination' => $return))); + } } /** @@ -179,8 +178,11 @@ function fb_devel_canvas_info() { else { // Followed a link from within an iframe. $info['Page Status'] = t('Global fb instance is set (followed link in iframe, or handling a form).'); + $info['fb'] = $fb; } $info['fb_facebook_user'] = fb_facebook_user(); + // users_isAppUser() may be unreliable! + $info['users_isAppUser'] = $fb->api_client->users_isAppUser(); } else { $info['Page Status'] = t('Not a canvas page.'); @@ -190,6 +192,9 @@ function fb_devel_canvas_info() { $info['base_url'] = $base_url; $info['base_path'] = $base_path; $info['url() returns'] = url(); + $info['$_REQUEST[q] is'] = $_REQUEST['q']; + $info['arg(0) is'] = arg(0); + $info['arg(1) is'] = arg(1); $info['session_id'] = session_id(); $info['session_name'] = session_name(); @@ -197,6 +202,11 @@ function fb_devel_canvas_info() { $info['fb_app'] = $fb_app; $info['session'] = $_SESSION; $info['cookies'] = $_COOKIE; + + if ($fb) { + $info['api_client'] = $fb->api_client; + } + $form = array(); foreach ($info as $key => $val) { if (is_string($val) || is_numeric($val) || !$val) { Index: fb_feed.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_feed.info,v retrieving revision 1.2 diff -u -p -r1.2 fb_feed.info --- fb_feed.info 5 Feb 2009 03:34:50 -0000 1.2 +++ fb_feed.info 22 Feb 2009 21:49:05 -0000 @@ -1,4 +1,5 @@ name = DFF Feeds description = Manage Facebook feed templates and post to feeds. package = Drupal for Facebook -dependencies = fb +dependencies[] = fb +core = 6.x Index: fb_feed.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_feed.module,v retrieving revision 1.9 diff -u -p -r1.9 fb_feed.module --- fb_feed.module 2 Feb 2009 19:35:37 -0000 1.9 +++ fb_feed.module 22 Feb 2009 21:49:05 -0000 @@ -16,39 +16,31 @@ define('FB_FEED_NODE_TYPE_TEMPLATE', 'fb define('FB_FEED_HOOK', 'fb_feed'); define('FB_FEED_OP_TOKEN_ALTER', 'fb_feed_token_alter'); -function fb_feed_menu($may_cache) { +function fb_feed_menu() { $items = array(); - if ($may_cache) { - $items[] = array('path' => 'fb_feed/register', - 'title' => t('Register template'), - 'type' => MENU_CALLBACK, - 'access' => user_access('administer fb apps'), - 'callback' => 'fb_feed_register_cb', - ); - $items[] = array('path' => 'fb_feed/deactivate', - 'title' => t('Deactivate template'), - 'type' => MENU_CALLBACK, - 'access' => user_access('administer fb apps'), - 'callback' => 'drupal_get_form', - 'callback arguments' => array('fb_feed_deactivate_confirm'), - ); - - } - else { - if (arg(0) == 'node' && is_numeric(arg(1))) { - $node = node_load(arg(1)); - if ($node->type == 'fb_app') { - $fb_app_data = fb_app_get_data($node->fb_app); - $items[] = array('path' => "node/$node->nid/fb_feed/templates", - 'title' => t('Feed Templates'), - 'type' => MENU_LOCAL_TASK, - 'access' => node_access('update', $node), - 'callback' => 'fb_feed_template_page', - 'callback arguments' => array($node->nid), - ); - } - } - } + $items['fb_feed/register'] = array( + 'title' => 'Register template', + 'type' => MENU_CALLBACK, + 'access arguments' => array('adminster fb apps'), + 'page callback' => 'fb_feed_register_cb', + ); + $items['fb_feed/deactivate'] = array( + 'title' => 'Deactivate template', + 'type' => MENU_CALLBACK, + 'access arguments' => array('adminster fb apps'), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('fb_feed_deactivate_confirm'), + ); + + $items['node/%fb_app_nid/fb_feed/templates'] = array( + 'title' => t('Feed Templates'), + 'type' => MENU_LOCAL_TASK, + 'access callback' => 'node_access', + 'access arguments' => array('update', 1), + 'page callback' => 'fb_feed_template_page', + 'page arguments' => array(1), + ); + return $items; } @@ -112,7 +104,7 @@ function fb_feed_register_cb($nid) { drupal_goto('node/'.$node->fb_app_nid.'/fb_feed/templates'); } -function fb_feed_template_page($fb_app_nid) { +function fb_feed_template_page($fb_app) { $registered = array(); $unregistered = array(); // Query all known templates @@ -127,7 +119,6 @@ function fb_feed_template_page($fb_app_n } // Query facebook for a list of registered templates we know nothing about. - $fb_app = fb_get_app(array('nid' => $fb_app_nid)); $fb = fb_api_init($fb_app, FB_FBU_ANY); if ($fb) { try { Index: fb_form.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_form.info,v retrieving revision 1.3 diff -u -p -r1.3 fb_form.info --- fb_form.info 5 Feb 2009 03:34:50 -0000 1.3 +++ fb_form.info 22 Feb 2009 21:49:05 -0000 @@ -1,4 +1,5 @@ name = DFF Forms description = Enables FBML form elements via Drupal Form API. Provides commonly needed forms such as invite friends to install application. package = Drupal for Facebook -dependencies = fb +dependencies[] = fb +core = 6.x Index: fb_form.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_form.module,v retrieving revision 1.13 diff -u -p -r1.13 fb_form.module --- fb_form.module 26 Sep 2008 20:06:30 -0000 1.13 +++ fb_form.module 22 Feb 2009 21:49:05 -0000 @@ -15,30 +15,27 @@ /** * hook_menu. */ -function fb_form_menu($may_cache) { +function fb_form_menu() { $items = array(); - if ($may_cache) { - // Page allowing a user to invite their friends to add the app. - $items[] = array('path' => 'fb/invite', - 'callback' => 'fb_form_invite_page', - 'access' => TRUE, - 'type' => MENU_CALLBACK, - ); - $items[] = array('path' => 'fb_form_friend_selector_autocomplete', - 'callback' => 'fb_form_friend_selector_autocomplete', - 'access' => TRUE, - 'type' => MENU_CALLBACK, - ); - } + // Page allowing a user to invite their friends to add the app. + $items['fb/invite'] = + array('page callback' => 'fb_form_invite_page', + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); + $items['fb_form_friend_selector_autocomplete'] = + array('page callback' => 'fb_form_friend_selector_autocomplete', + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, + ); return $items; } /** * hook_form_alter. */ -function fb_form_form_alter($form_id, &$form) { - // Drupal allows no clean way to set $form['#type'], so we hack. - +function fb_form_form_alter(&$form, &$form_state, $form_id) { + /* Drupal allows no clean way to set $form['#type'], so we hack... */ if ($type = $form['#fb_form_type_hack']) { $form['#type'] = $type; unset($form['#fb_form_type_hack']); @@ -121,7 +118,7 @@ function fb_form_invite_page() { if (function_exists('fb_canvas_is_fbml') && !fb_canvas_is_fbml()) { - drupal_set_message(t('Unable to display page. FBML required.'), 'error'); + drupal_set_message('Unable to display page. FBML required.', 'error'); drupal_not_found(); exit(); } @@ -259,7 +256,7 @@ function fb_form_friend_options($fbu) { $items = array(); if ($fb) { - $query = "SELECT last_name, first_name, uid, pic_square FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$fbu)"; + $query = "SELECT last_name, first_name, uid, pic_square FROM user WHERE uid IN (SELECT uid2 FROM friend WHERE uid1=$fbu)"; //TODO: db_query this to be safe? $result = $fb->api_client->fql_query($query); // TODO: sort results by name @@ -273,14 +270,14 @@ function fb_form_friend_options($fbu) { function fb_form_group_member_options($fbg, $fbu) { global $fb; - $query = "SELECT uid FROM group_member WHERE gid=$fbg"; + $query = "SELECT uid FROM group_member WHERE gid=$fbg"; //TODO: db_query this? $result = $fb->api_client->fql_query($query); drupal_set_message("fb_form_group_member_options($fbg, $fbu) query $query returns" . dpr($result, 1)); - $query = "SELECT uid, first_name, last_name FROM user WHERE uid IN (SELECT uid FROM group_member WHERE gid=$fbg)"; + $query = "SELECT uid, first_name, last_name FROM user WHERE uid IN (SELECT uid FROM group_member WHERE gid=$fbg)"; //TODO: db_query to be safe? $result = $fb->api_client->fql_query($query); drupal_set_message("fb_form_group_member_options($fbg, $fbu) query $query returns" . dpr($result, 1)); @@ -384,7 +381,7 @@ function fb_form_friend_selector_process else $element['#type'] = 'textfield'; - $element['#autocomplete_path'] = url('fb_form_friend_selector_autocomplete', NULL, NULL, TRUE); + $element['#autocomplete_path'] = url('fb_form_friend_selector_autocomplete', array('absolute' => TRUE)); return $element; } @@ -472,6 +469,14 @@ function fb_form_friend_selector_validat _form_set_value($_POST, $element, $element['#parents'], $items); } +function fb_form_theme() { + return array( + 'friend_selectorXXX' => array( + 'arguments' => array('fbu' => NULL), + ), + ); +} + // TODO: provide some alternative when NOT a facebook app. // deprecated! function theme_fb_form_friend_selector($fbu = NULL) { @@ -482,4 +487,3 @@ function theme_fb_form_friend_selector($ $output = ""; return $output; } -?> \ No newline at end of file Index: fb_infinite.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_infinite.info,v retrieving revision 1.2 diff -u -p -r1.2 fb_infinite.info --- fb_infinite.info 5 Feb 2009 03:34:50 -0000 1.2 +++ fb_infinite.info 22 Feb 2009 21:49:05 -0000 @@ -1,5 +1,5 @@ name = DFF Infinite Session description = Some app administration requires a session. Use this module, or Facebook Connect, with the Feeds module. package = Drupal for Facebook -dependencies = fb fb_app - +dependencies[] = fb +core = 6.x Index: fb_infinite.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_infinite.module,v retrieving revision 1.7 diff -u -p -r1.7 fb_infinite.module --- fb_infinite.module 2 Feb 2009 19:36:27 -0000 1.7 +++ fb_infinite.module 22 Feb 2009 21:49:05 -0000 @@ -27,43 +27,51 @@ function fb_infinite_fb($op, $data, &$re /** * hook_menu */ -function fb_infinite_menu($may_cache) { - $items = array(); - if ($may_cache) { - $items[] = array('path' => 'fb/infinite/display', - 'title' => t('Facebook session information'), - 'access' => TRUE, - 'callback' => 'fb_infinite_display_page', - 'type' => MENU_CALLBACK, +function fb_infinite_menu() { + $items['fb/infinite/display'] = + array('title' => t('Facebook session information'), + 'page callback' => 'fb_infinite_display_page', + 'access callback' => TRUE, + 'type' => MENU_CALLBACK, ); - } - else { - if (arg(0) == 'node' && is_numeric(arg(1))) { - $node = node_load(arg(1)); - if ($node->type == 'fb_app') { - // Only show if infinite session is configured. - $fb_app_data = fb_app_get_data($node->fb_app); - $fb_infinite_data = $fb_app_data['fb_infinite']; - if ($fb_infinite_data['key']) { - $items[] = array('path' => "node/$node->nid/fb/infinite/test", - 'title' => t('Infinite session test'), - 'type' => MENU_LOCAL_TASK, - 'access' => node_access('update', $node), - 'callback' => 'fb_infinite_test_page', - 'callback arguments' => array($node->nid), - ); - } - } + + $items['node/%fb_infinite/fb/infinite/test'] = + array('title' => 'Infinite session test', + 'page callback' => 'fb_infinite_test_page', + 'page arguments' => array(1), + 'access callback' => 'node_access', + 'access arguments' => array('update', 1), + 'type' => MENU_LOCAL_TASK, + ); + + return $items; +} + + +/** + * Implementation of hook_load to create custom loader for hook_menu + * Checks a fb_app nid to see if infinite session is configured + * + * see "Defining your own wildcard loader" - http://drupal.org/node/209056 + * passing $nid not needed if menu_get_object were to work + */ +function fb_infinite_load($nid) { + $fb_app = fb_get_app(array('nid' => $nid)); + if ($fb_app) { + // Only allow menu item if infinite session is configured. + $fb_app_data = fb_app_get_data($fb_app); + $fb_infinite_data = $fb_app_data['fb_infinite']; + if (isset($fb_infinite_data['key'])) { + return $fb_app; } } - return $items; } /** * Implementation of hook_form_alter. */ -function fb_infinite_form_alter($form_id, &$form) { - //drupal_set_message("fb_infinte_form_alter($form_id) " . dpr($form, 1)); +function fb_infinite_form_alter(&$form, &$form_state, $form_id) { + //drupal_set_message("fb_infinite_form_alter($form_id) " . dpr($form, 1)) . dpr($form_state, 1)); // Add our settings to the fb_app edit form. if (is_array($form['fb_app_data'])) { @@ -120,7 +128,7 @@ function fb_infinite_form_alter($form_id function fb_infinite_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { if ($node->type == 'fb_app') { - if ($op == 'submit') { + if ($op == 'presave') { $fb_app_data = $node->fb_app_data; $fb_infinite_data = $fb_app_data['fb_infinite']; @@ -169,14 +177,13 @@ function fb_infinite_display_page() { /** * Menu callback to test infinite session values. */ -function fb_infinite_test_page($nid) { +function fb_infinite_test_page($fb_app) { if ($GLOBALS['fb']) { $url = $GLOBALS['fb_old_base_url'] . "?q=".$_GET['q']; return t('Do not use this page from a canvas page. Try !link.', array('!link' => l($url, $url))); } - - $fb_app = fb_get_app(array('nid' => $nid)); + $fb = fb_api_init($fb_app, FB_FBU_INFINITE_SESSION); if ($fb) { $fbu = $fb->api_client->users_getLoggedInUser(); @@ -206,11 +213,11 @@ function fb_infinite_test_page($nid) { } } else { - drupal_set_message(t('Infinite session key test failed.'), 'error'); - $output .= '

'.t('Unable to log initialize Facebook API.').'

'; + drupal_set_message('Infinite session key test failed.', 'error'); + // TODO: provide helpful hints of how to fix the problem. + $output .= '

'.t('Unable to log into Facebook using infinite session key.').'

'; } - + return $output; } -?> \ No newline at end of file Index: fb_session.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_session.inc,v retrieving revision 1.4 diff -u -p -r1.4 fb_session.inc --- fb_session.inc 10 Feb 2009 23:39:59 -0000 1.4 +++ fb_session.inc 22 Feb 2009 21:49:05 -0000 @@ -54,12 +54,12 @@ else { $apikey = NULL; // Discover APIKEY by inspecting cookies. foreach ($_COOKIE as $key => $value) { - if (strpos($key, 'fbsetting_') === 0) { - $apikey = substr($key, 10); // strlen('fbsetting'); + if ($pos = strpos($key, '_session_key')) { + $apikey = substr($key, 0, $pos); } } - - if ($apikey && isset($_COOKIE[$apikey . '_session_key'])) { + + if ($apikey && isset($_COOKIE[$apikey])) { // We're logged into Facebook Connect. // Use globals to remember some values, for fb_connect.module to use. Index: fb_settings.inc =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_settings.inc,v retrieving revision 1.5 diff -u -p -r1.5 fb_settings.inc --- fb_settings.inc 10 Feb 2009 23:39:59 -0000 1.5 +++ fb_settings.inc 22 Feb 2009 21:49:05 -0000 @@ -5,6 +5,7 @@ define('FB_SETTINGS_APP_NID', 'fb_cb'); define('FB_SETTINGS_PAGE_TYPE', 'fb_cb_type'); define('FB_SETTINGS_SESSION_KEY', 'fb_sess'); +// NOTE: can't use variable_set() -- database.inc hasn't loaded yet, so db_query() in variable_set() fails if (!is_array($conf)) $conf = array(); @@ -47,20 +48,46 @@ if ($nid = _fb_settings_parse(FB_SETTING } /** - * Implementation of conf_url_rewrite + * Implementation of conf_url_rewrite_inbound * * Defines the URL rewrite if not defined already. If it is defined already, - * or your using 118n modules, you should define a custom_url_rewrite in - * settings.php which calls fb_canvas_url_rewrite in addition to any others + * or your using 118n modules, you should define a custom_url_rewrite_inbound in + * settings.php which calls fb_canvas_url_rewrite_inbound in addition to any others * that need to be called. The order will be important! */ -if(!function_exists('custom_url_rewrite')) { - function custom_url_rewrite($type, $path, $original) { - return fb_settings_url_rewrite($type, $path, $original); +//TODO: this needs confirmation. +//custom_url_rewrite was dropped in 6.x so I split the 'source' portion of the old function +//into _inbound and the 'alias' portion into _outbound versions +//really guessing here, but it seems to be working +if(!function_exists('custom_url_rewrite_inbound')) { + function custom_url_rewrite_inbound(&$result, $path, $path_language) { + fb_settings_url_rewrite_inbound($result, $path, $path_language); } } +if(!function_exists('custom_url_rewrite_outbound')) { + function custom_url_rewrite_outbound(&$path, $options, $original_path) { + fb_settings_url_rewrite_outbound($path, $options, $original_path); + } +} + +//TODO: especially verify this one - not sure what to do with Absolute paths, if anything +//TODO: problem with _fb_canvas_make_form_action_local - is it caused by this? +//TODO: I don't think the fb_canvas_is_fbml() and fb_canvas_is_iframe() functions are returning the right values either +function fb_settings_url_rewrite_outbound(&$path, $options, $original_path) { + //dpm(func_get_args(), 'fb_settings_url_rewrite_outbound'); + $pre = ''; + + // Prefix each known value to the URL + foreach (array_reverse(_fb_settings_url_rewrite_prefixes()) as $prefix) { + if ($value = fb_settings($prefix)) + $pre .= $prefix . '/'. $value . '/'; + } + $path = $pre . $path; + + return $path; +} /** * Rewrite URLs for facebook canvas pages. @@ -69,43 +96,43 @@ if(!function_exists('custom_url_rewrite' * set when serving canvas pages. However, it gets called before * modules are loaded. So it must live here. */ -function fb_settings_url_rewrite($type, $path, $original){ - //dpm(func_get_args(), 'fb_canvas_url_rewrite'); - //print("fb_canvas_url_rewrite($type, $path, $original)"); - $prefixes = array(FB_SETTINGS_APP_NID, FB_SETTINGS_PAGE_TYPE, FB_SETTINGS_SESSION_KEY); - if ($type == 'source') { - // See if this is a request for us. - if (strpos($path, FB_SETTINGS_APP_NID . '/') === 0) { - // Too soon for arg() function. - $args = explode('/', $path); - while (count($args) && in_array($args[0], $prefixes)) { - $key = array_shift($args); - $value = array_shift($args); - fb_settings($key, $value); // Store for use later. +function fb_settings_url_rewrite_inbound(&$result, $path, $path_language){ + //$origpath = $path; + //watchdog('fb_settings', "fb_settings_url_rewrite_inbound($result, $path, $path_language)", array(), WATCHDOG_DEBUG); + + // See if this is a request for us. + if (strpos($path, FB_SETTINGS_APP_NID . '/') === 0) { + // Too soon for arg() function. + $args = explode('/', $path); + while (count($args) && in_array($args[0], _fb_settings_url_rewrite_prefixes())) { + $key = array_shift($args); + $value = array_shift($args); + $app_nid = fb_settings($key, $value); // Store for use later. + } + if ($app_nid = fb_settings(FB_SETTINGS_APP_NID)) { + if (count($args)) { + $path = implode('/', $args); // remaining args + $alias = drupal_lookup_path('source', $path, $path_language); //can't use drupal_get_normal_path, it calls custom_url_rewrite_inbound + if ($alias) + $path = $alias; } - if ($app_nid = fb_settings(FB_SETTINGS_APP_NID)) { - if (count($args)) { - $path = implode('/', $args); // remaining args - $path = drupal_get_normal_path($path); - } - else - // frontpage - $path = drupal_get_normal_path(variable_get('site_frontpage', 'node')); + else { + // frontpage + $path = variable_get('site_frontpage', 'node'); + $alias = drupal_lookup_path('source', $path, $path_language); + if ($alias) + $path = $alias; + $_REQUEST['destination'] = $path; //required workaround for compatibility with Global Redirect module, best practice? } - } - } - else if ($type == 'alias') { - $pre = ''; - - // Prefix each known value to the URL - foreach ($prefixes as $prefix) { - if ($value = fb_settings($prefix)) - $pre .= $prefix . '/'. $value . '/'; } - $path = $pre . $path; + } + else { //resolve aliases for non-fb-callbacks + $alias = drupal_lookup_path('source', $path, $path_language); + if ($alias) + $path = $alias; } - return $path; + $result = $path; } function fb_settings($key, $value = NULL) { @@ -117,6 +144,17 @@ function fb_settings($key, $value = NULL } /** + * Returns a list of the values which we prepend to paths when rewriting urls. + */ +function _fb_settings_url_rewrite_prefixes() { + static $prefixes; + if (!isset($prefixes)) { + $prefixes = array(FB_SETTINGS_APP_NID, FB_SETTINGS_PAGE_TYPE, FB_SETTINGS_SESSION_KEY); + } + return $prefixes; +} + +/** * Parse a setting from the URL. This may be called before * custom_url_rewrite, so we can't count on fb_settings() to return the value. * For internal use only (see fb_session.inc). @@ -139,5 +177,3 @@ function _fb_settings_parse($key) { } } - -?> \ No newline at end of file Index: fb_user.info =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_user.info,v retrieving revision 1.2 diff -u -p -r1.2 fb_user.info --- fb_user.info 5 Feb 2009 03:34:50 -0000 1.2 +++ fb_user.info 22 Feb 2009 21:49:05 -0000 @@ -1,5 +1,6 @@ name= DFF User Management description = Create local accounts for users of Facebook Apps. package = Drupal for Facebook -dependencies = fb fb_app - +dependencies[] = fb +dependencies[] = fb_app +core = 6.x Index: fb_user.install =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_user.install,v retrieving revision 1.3 diff -u -p -r1.3 fb_user.install --- fb_user.install 20 May 2008 05:37:52 -0000 1.3 +++ fb_user.install 22 Feb 2009 21:49:05 -0000 @@ -1,39 +1,38 @@ $db_type)), 'error'); - } - foreach ($query as $q) { - $status = db_query ($q); - if (!$status) { - drupal_set_message(t('Error installing fb_user: %error %query', - array('%query' => '
'.$q.'
', - '%error' => db_error())), - 'error'); - } - } + // Create tables. + drupal_install_schema('fb_user'); +} + + +/** + * Implementation of hook_uninstall(). + */ +function fb_user_uninstall() { + // Remove tables. + drupal_uninstall_schema('fb_user'); +} + + +function fb_user_schema() { + $schema['fb_user_app'] = + array('fields' => array('apikey' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, ), + 'fbu' => array('type' => 'int', 'length' => 11, 'unsigned' => TRUE, 'not null' => TRUE, ), + 'uid' => array('type' => 'int', 'size' => 'normal', 'not null' => TRUE, ), + 'added' => array('type' => 'int', 'length' => 4, 'unsigned' => TRUE, 'not null' => TRUE, ), + 'time_cron' => array('type' => 'int', 'length' => 11, 'unsigned' => TRUE, 'not null' => TRUE, ), + 'time_access' => array('type' => 'int', 'length' => 11, 'unsigned' => TRUE, 'not null' => TRUE, ), + 'session_key' => array('type' => 'varchar', 'length' => 128, 'not null' => TRUE, ), + 'session_key_expires' => array('type' => 'int', 'length' => 11, 'unsigned' => TRUE, 'not null' => TRUE, ), + ), + 'primary key' => array('apikey', 'fbu'), + ); + return $schema; } function fb_user_update_1() { Index: fb_user.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/fb_user.module,v retrieving revision 1.28 diff -u -p -r1.28 fb_user.module --- fb_user.module 14 Jan 2009 22:56:33 -0000 1.28 +++ fb_user.module 22 Feb 2009 21:49:05 -0000 @@ -45,7 +45,7 @@ function _fb_user_track($fb, $fb_app, $u if (!$user->uid || $user->uid == $fb_user_data['not_logged_in_uid'] || $user->uid == $fb_user_data['logged_in_uid']) { $result =db_query("REPLACE INTO {fb_user_app} (apikey, fbu, added, time_access, session_key, session_key_expires) VALUES ('%s', %d, %d, %d, '%s', %d)", $fb_app->apikey, fb_facebook_user(), - $fb->api_client->users_isAppUser(), time(), + fb_is_app_user($fb), time(), $fb->api_client->session_key, $_REQUEST['fb_sig_expires'] ); } @@ -54,7 +54,7 @@ function _fb_user_track($fb, $fb_app, $u $result =db_query("REPLACE INTO {fb_user_app} (apikey, fbu, uid, added, time_access, session_key, session_key_expires) VALUES ('%s', %d, %d, %d, %d, '%s', %d)", $fb_app->apikey, fb_facebook_user(), $user->uid, - $fb->api_client->users_isAppUser(), time(), + fb_is_app_user($fb), time(), $fb->api_client->session_key, $_REQUEST['fb_sig_expires'] ); } @@ -145,7 +145,7 @@ function fb_user_fb($op, $data, &$return // Check if we need to create a local account for this user. if (($fb_user_data['create_account'] == FB_USER_OPTION_CREATE_ADD && - $fb->api_client->users_isAppUser()) || + fb_is_app_user($fb)) || ($fb_user_data['create_account'] == FB_USER_OPTION_CREATE_LOGIN)) { // Check if the local account is already made. @@ -185,7 +185,7 @@ function fb_user_fb($op, $data, &$return (!$_REQUEST['fb_sig_in_profile_tab'])) { // Redirect to a canvas page - $url = fb_canvas_fix_url(url(fb_scrub_urls($_REQUEST['q']), NULL, NULL, TRUE), $fb_app); + $url = fb_canvas_fix_url(url(fb_scrub_urls($_REQUEST['q']), array('absolute' => TRUE)), $fb_app); if (fb_verbose()) watchdog('fb_debug', "User uid is now {$user->uid} (was {$original_uid}), redirecting to $url to ensure permissions are correct."); // debug $fb->redirect($url); @@ -194,21 +194,7 @@ function fb_user_fb($op, $data, &$return // Keep a record of when user accesses app, and whether they have added it. _fb_user_track($fb, $fb_app, $user); - - // We don't want user's who are not logged in (in the facebook sense) to - // login locally. So let's make sure they've added the app before doing - // anything related to Drupal accounts. - /** I _think_ the new api no longer requires this. TODO: confirm. - if (strpos($_GET['q'],'user/login') === 0) { - // Have to check idAppUser in case of iframe. - if (!$fb->api_client->users_isAppUser()) - $fb->require_login(); - } - else if (strpos($_GET['q'],'user/register') === 0) { - if (!$fb->api_client->users_isAppUser()) - $fb->require_login(); - } - */ + // Now do I need a goto or some such??? // debug @@ -286,7 +272,7 @@ function fb_user_authentication_is_requi } } -function fb_user_form_alter($form_id, &$form) { +function fb_user_form_alter(&$form, &$form_state, $form_id) { //drupal_set_message("fb_user_form_alter($form_id) " . dpr($form, 1)); // Add our settings to the fb_app edit form. @@ -565,7 +551,7 @@ function fb_user_user($op, &$edit, &$acc else { // Non-fbml page // TODO: use API to hide permissions we already have - $url = url($_GET['q'], NULL, NULL, TRUE); + $url = url($_GET['q'], array('absolute' => TRUE)); $form[$key] = array('#type' => 'markup', '#value' => l(t($t, array('%application' => $fb_app->title)), @@ -699,7 +685,7 @@ function fb_user_create_local_user($fb, $account = user_save('', $user_default); - watchdog('fb_user', t('New user: %name %email.', array('%name' => $name, '%email' => '<'. $mail .'>')), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit')); + watchdog('fb_user', 'New user: %name %email.', array('%name' => $name, '%email' => '<'. $mail .'>'), WATCHDOG_NOTICE, l(t('edit'), 'user/'. $account->uid .'/edit')); // Allow third-party modules to act after account creation. //$config = fb_invoke($fb_app, FB_OP_POST_USER, NULL, array('account' => $account)); @@ -710,8 +696,8 @@ function fb_user_create_local_user($fb, // TODO: move this to fb_action. Temporarily disabled. if (FALSE) { // Prepare to send an email. - $base = url('', NULL, NULL, TRUE); - $variables = array('!username' => $account->name, '!site' => variable_get('site_name', 'Drupal'), '!password' => $user_default['pass'], '!uri' => $base, '!uri_brief' => substr($base, strlen('http://')), '!mailto' => $mail, '!date' => format_date(time()), '!login_uri' => url('user', NULL, NULL, TRUE), '!edit_uri' => url('user/'. $account->uid .'/edit', NULL, NULL, TRUE), '!login_url' => user_pass_reset_url($account)); + $base = url('', array('absolute' => TRUE)); + $variables = array('!username' => $account->name, '!site' => variable_get('site_name', 'Drupal'), '!password' => $user_default['pass'], '!uri' => $base, '!uri_brief' => substr($base, strlen('http://')), '!mailto' => $mail, '!date' => format_date(time()), '!login_uri' => url('user', array('absolute' => TRUE)), '!edit_uri' => url('user/'. $account->uid .'/edit', array('absolute' => TRUE)), '!login_url' => user_pass_reset_url($account)); $subject = _user_mail_text('welcome_subject', $variables); $body = _user_mail_text('welcome_body', $variables); @@ -847,5 +833,3 @@ function fb_user_token_values($type = 'a return $values; } - -?> \ No newline at end of file Index: themes/fb_fbml/fb_fbml.info =================================================================== RCS file: themes/fb_fbml/fb_fbml.info diff -N themes/fb_fbml/fb_fbml.info --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ themes/fb_fbml/fb_fbml.info 22 Feb 2009 21:49:05 -0000 @@ -0,0 +1,11 @@ +name = fb_fbml +description = Use on Facebook FBML canvas pages only. +core = 6.x +engine = phptemplate + +regions[admin] = Admin sidebar +regions[header] = Canvas Header +regions[right] = Canvas Right +regions[content_footer] = Content Footer +regions[canvas_footer] = Canvas Footer + Index: themes/fb_fbml/node.tpl.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/themes/fb_fbml/node.tpl.php,v retrieving revision 1.4 diff -u -p -r1.4 node.tpl.php --- themes/fb_fbml/node.tpl.php 27 Mar 2008 22:13:43 -0000 1.4 +++ themes/fb_fbml/node.tpl.php 22 Feb 2009 21:49:05 -0000 @@ -10,6 +10,7 @@ if ($extra_style) ?>
> +
+
- + Index: themes/fb_fbml/styles_fbml.css =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/themes/fb_fbml/styles_fbml.css,v retrieving revision 1.3 diff -u -p -r1.3 styles_fbml.css --- themes/fb_fbml/styles_fbml.css 6 Nov 2008 20:20:27 -0000 1.3 +++ themes/fb_fbml/styles_fbml.css 22 Feb 2009 21:49:05 -0000 @@ -1,6 +1,6 @@ - .page-wrap { - position: relative; - } +.page-wrap { + position: relative; +} .page-wrap.in-new-facebook { width: 760px; } div.error { @@ -80,6 +80,7 @@ .header ul.links, .header .block-menu { float: right; + clear: right; } .header .block .content {clear: none;} @@ -150,17 +151,17 @@ /* Give some links the facebook button look */ a.fb_button { - background:#526EA6 url(http://www.facebook.com/images/pandemic/white_arrow_on_blue.gif) no-repeat scroll right center; - border-color:#145C9A rgb(14, 31, 91) rgb(14, 31, 91) rgb(20, 92, 154); - border-style:solid; - border-width:1px; + background:#526EA6 url(http://www.facebook.com/images/pandemic/white_arrow_on_blue.gif) no-repeat scroll right center; + border-color:#145C9A rgb(14, 31, 91) rgb(14, 31, 91) rgb(20, 92, 154); + border-style:solid; + border-width:1px; color:#FFFFFF; font-weight:bold; padding:3px 24px 5px 15px; } a.fb_button:hover { background-color:#40578A; - text-decoration:none; + text-decoration:none; } table { Index: themes/fb_fbml/template.php =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/fb/themes/fb_fbml/template.php,v retrieving revision 1.13 diff -u -p -r1.13 template.php --- themes/fb_fbml/template.php 12 Oct 2008 15:43:14 -0000 1.13 +++ themes/fb_fbml/template.php 22 Feb 2009 21:49:05 -0000 @@ -1,17 +1,48 @@ array(), + 'content' => $content, + 'show_blocks' => $show_blocks, + 'show_messages' => $show_messages, + ); + $hook = 'page'; + + // We have to go out of our way here to theme the tabs. + + // The code in menu.inc that themes them is complex, + // incomprehensible, and tangles the theme layer with the logic + // layer. It doesn't help that the same theme functions are called + // for tabs as are called for all other menus. So we use a global + // to keep track of what we're doing. + global $_fb_fbml_state; + $_fb_fbml_state = 'tabs'; + // Why does a call to menu_tab_root_path theme the tabs? I have no + // idea, but it does and caches the result. + menu_tab_root_path(); + $_fb_fbml_state = NULL; + + template_preprocess($variables, $hook); + template_preprocess_page($variables, $hook); + // If any modules implement a preprocess function, they're SOL, we don't know about it. + + // Now our own preprocessing + fb_fbml_preprocess($variables, $hook); + + $template_file = path_to_theme() . '/page.tpl.php'; + $output = theme_render_template($template_file, $variables); if (function_exists('fb_canvas_process')) { $output = fb_canvas_process($output); } return $output; - } -function _phptemplate_variables($hook, $vars = array()) { +function fb_fbml_preprocess(&$vars, $hook) { global $fb_app, $user; if ($hook == 'page') { @@ -71,17 +102,17 @@ function _phptemplate_variables($hook, $ // Style page differently depending on which sidebars are present. // Approach copied from Zen theme. - // allows advanced theming based on context (home page, node of certain type, etc.) + // allows styling based on context (home page, node of certain type, etc.) $body_classes = array(); $body_classes[] = ($vars['is_front']) ? 'front' : 'not-front'; $body_classes[] = ($user->uid > 0) ? 'logged-in' : 'not-logged-in'; - if ($vars['sidebar_left'] && $vars['sidebar_right']) { + if ($vars['left'] && $vars['right']) { $body_classes[] = 'with-both-sidebars'; } - else if ($vars['sidebar_right']) { + else if ($vars['right']) { $body_classes[] = 'with-sidebar-right'; } - else if ($vars['sidebar_left']) { + else if ($vars['left']) { $body_classes[] = 'with-sidebar-left'; } @@ -90,23 +121,22 @@ function _phptemplate_variables($hook, $ $body_classes[] = 'in-new-facebook'; $vars['body_classes'] = implode(' ', $body_classes); - } } else if ($hook == 'node') { if ($vars['teaser']) { $vars['template_file'] = 'node-teaser'; } - + // TODO: could move this to phptemplate engine. if (count($vars['about'])) $vars['about'] = drupal_render($vars['about']); if (count($vars['children'])) $vars['children'] = drupal_render($vars['children']); - + if ($vars['extra_style']) $vars['extra_style'] = drupal_render($vars['extra_style']); - + if ($vars['teaser']) $size = 'thumb'; else @@ -116,7 +146,6 @@ function _phptemplate_variables($hook, $ //drupal_set_message("node vars: " . dprint_r($vars, 1)); } - return $vars; } function fb_fbml_regions() { @@ -132,37 +161,64 @@ function fb_fbml_regions() { } //// tabs +function fb_fbml_menu_local_task($link, $active = FALSE) { + global $_fb_fbml_state; + + if ($_fb_fbml_state == 'tabs') { + if ($active) { + $link = str_replace('selected="false"', 'selected="true"', $link); + } + return $link; + } + else + return theme_menu_local_task($link, $active); +} + +function fb_fbml_menu_item_link($link) { + global $_fb_fbml_state; -function phptemplate_menu_local_tasks() { + if ($_fb_fbml_state == 'tabs') { + // Theme an FBML tab + $output .= "".$item['title']."\n"; + return $output; + } + else + return theme_menu_item_link($link, $active); +} + +function fb_fbml_menu_local_tasks() { global $fb; + // Because menu.inc's navigation of the menu tree is too complicated + // to understand, or reproduce here, we need to maintain state as the + // menu tree is navigated. + global $_fb_fbml_state; + $_fb_fbml_state = 'argh'; + if ($fb && $fb->in_fb_canvas()) { - $local_tasks = menu_get_local_tasks(); - $pid = menu_get_active_nontask_item(); $output = ''; - if (count($local_tasks[$pid]['children'])) { - $output .= "\n"; - foreach ($local_tasks[$pid]['children'] as $mid) { - $item = menu_get_item($mid); - $selected = menu_in_active_trail($mid) ? "true" : "false"; - $output .= "".$item['title']."\n"; - } - $output .= "\n"; - } - // TODO secondary local tasks + $_fb_fbml_state = 'primary'; + if ($primary = menu_primary_local_tasks()) { + $output .= "\n". $primary ."\n"; + } + + $_fb_fbml_state = 'secondary'; + if ($secondary = menu_secondary_local_tasks()) { - $output .= "\n"; + // TODO: use fbml for secondary tabs + $output .= "\n"; } + $_fb_fbml_state = NULL; + } - else + else { $output = theme_menu_local_tasks(); - + } return $output; - } // collapsing fieldsets -function phptemplate_fieldset($element) { +function fb_fbml_fieldset($element) { global $fb; if (($fb && $fb->in_fb_canvas()) || (function_exists('fb_canvas_is_fbml') && fb_canvas_is_fbml())) {