'fb_tab_view', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); $items[FB_TAB_PATH_FORM] = array( 'title' => 'Configure Tabs', 'page callback' => 'fb_tab_pages', 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); $items[FB_TAB_PATH_FORM . '/%'] = array( 'page callback' => 'drupal_get_form', 'page arguments' => array('fb_tab_config_form', FB_TAB_PATH_FORM_ARGS), 'access arguments' => array('access content'), 'type' => MENU_CALLBACK, ); return $items; } /** * Implements hook_fb * * @param $op * @param $data -- data payload * @param $return */ function fb_tab_fb($op, $data, &$return) { $fb = isset($data['fb']) ? $data['fb'] : NULL; $fb_app = isset($data['fb_app']) ? $data['fb_app'] : NULL; if ($op == FB_OP_POST_INIT) { // Include our admin hooks. if (fb_is_fb_admin_page()) { require drupal_get_path('module', 'fb_tab') . '/fb_tab.admin.inc'; } } elseif ($op == FB_OP_CURRENT_APP) { if (fb_is_tab() && isset($_REQUEST['fb_sig_api_key'])) { $return = fb_get_app(array('apikey' => $_REQUEST['fb_sig_api_key'])); } } elseif ($op == FB_OP_INITIALIZE) { if (fb_is_tab()) { $config = _fb_tab_get_config($fb_app); if (!isset($GLOBALS['custom_theme'])) { $GLOBALS['custom_theme'] = $config['custom_theme']; } $use_ob = variable_get(FB_TAB_VAR_PROCESS, TRUE); // Hack to init the theme before _drupal_maintenance_theme initializes the wrong one. if (variable_get('site_offline', FALSE)) { $dummy = theme('dummy'); } // Store entire page in output buffer. Will post-process on exit. if ($use_ob) { ob_start(); $GLOBALS['fb_tab_post_process'] = TRUE; } } } elseif ($op == FB_OP_EXIT && fb_is_tab()) { if (isset($GLOBALS['fb_tab_post_process']) && $GLOBALS['fb_tab_post_process']) { $output = ob_get_contents(); ob_end_clean(); //print '
' . htmlentities($output) . ''; flush(); $output = fb_canvas_process($output, array( 'add_target' => FALSE, 'absolute_links' => TRUE, )); if (isset($output)) { print($output); } } } } /** * Implements fb_tab_form_alter. */ function fb_tab_form_alter(&$form, &$form_state, $form_id) { if (isset($form['fb_app_data']) && is_array($form['fb_app_data'])) { // Add our settings to the fb_app edit form. //require 'fb_canvas.admin.inc'; fb_tab_admin_form_alter($form, $form_state, $form_id); } if (fb_is_tab()) { // Most Drupal forms have an action that assumes Drupal's base_path. // But in the case of FBML, we need to make it explicit. $form['#action'] = url(request_path(), array('absolute' => TRUE)); //dpm(__FUNCTION__ . " changed action to " . $form['#action']); } } function _fb_tab_make_form_action_local($action = NULL) { global $base_path; if (!isset($action)) { // Is this ever reached? $action = request_path(); } // If action is fully qualified, do not change it if (strpos($action, ':')) { return $action; } $relative = url(''); $absolute = url('', array('absolute' => TRUE)); $base_path = base_path(); // By default, '#action' will be request_uri(), which starts with base_path(); global $_fb_app; if (strpos($action, $relative) === 0) { // If here, the action was made by call to url() and we prepended // canvas_name. Now remove the canvas name for a proper absolute url. // (Comment forms reach this clause but node forms do not.) $action = substr($action, strlen($relative)); } elseif ($base_path && strpos($action, $base_path) === 0) { $action = substr($action, strlen($base_path)); } $action = url(ltrim($action, '/'), array('absolute' => TRUE)); return $action; } /** * Helper returns configuration for this module, on a per-app basis. */ function _fb_tab_get_config($fb_app) { $fb_app_data = fb_get_app_data($fb_app); $config = isset($fb_app_data['fb_tab']) ? $fb_app_data['fb_tab'] : array(); // Merge in defaults $config += array( 'custom_theme' => NULL, 'tab_default_name' => isset($fb_app->title) ? $fb_app->title : NULL, 'profile_tab_url' => FB_TAB_PATH_VIEW, ); return $config; } /** * Another module provides the contents of the tab depending * on the context that we give it (who is calling it, etc.) */ function fb_tab_view() { $fb_app = $GLOBALS['_fb_app']; $fb = $GLOBALS['_fb']; $profile_id = fb_settings(FB_SETTINGS_PROFILE_ID); $config = fb_tab_fetch_config($fb_app, $profile_id); $data = array( 'fb_app' => $fb_app, 'fb' => $fb, 'profile_id' => $profile_id, 'config' => isset($config['data']) ? $config['data'] : NULL, ); $content = fb_invoke(FB_TAB_OP_VIEW, $data, array(), FB_TAB_HOOK); //print('
' . print_r($data, 1) . ''); flush(); //print(print_r($content, 1)); flush(); return drupal_render($content); } /** * Build the tab config form. Invokes hook_fb_tab() to get the custom settings. */ function fb_tab_config_form($form_state, $profile_id) { $fb_app = $GLOBALS['_fb_app']; $fb = $GLOBALS['_fb']; $config = fb_tab_fetch_config($fb_app, $profile_id); $data = array( 'fb_app' => $fb_app, 'fb' => $fb, 'profile_id' => $profile_id, 'config' => isset($config['data']) ? $config['data'] : NULL, ); //$fbu = fb_facebook_user($fb); $fbu = fb_require_authorization($fb); try { $page_info = $fb->api($profile_id, array( 'access_token' => fb_get_token($fb), )); $admin_info = fb_fql_query($fb, "SELECT uid, type FROM page_admin WHERE uid=$fbu AND page_id=$profile_id"); // FQL not SQL, no {curly_brackets} //dpm($admin_info, __FUNCTION__); // @TODO: if not page admin, prompt user to login or deny access. $form = array( 'info' => array( '#type' => 'markup', '#value' => t('Tab settings for %page', array( '!href' => $page_info['link'], '%page' => $page_info['name'], )), '#prefix' => '
' . print_r($data, 1) . ''); flush(); //print(print_r($content, 1)); flush(); return $form; } catch (Exception $e) { fb_log_exception($e, t('Failed to get details for facebook page %profile_id', array( '%profile_id' => $profile_id, ))); return array( 'error' => array( '#value' => t('Unable to set properties.'), ), ); } } /** * Submit handler for tab config form. */ function fb_tab_config_form_submit($form, &$form_state) { if ($profile_id = $form_state['values']['profile_id']) { fb_tab_write_config($form_state['values']); $data = fb_fql_query($GLOBALS['_fb'], "SELECT page_id, name, pic_small, page_url, type FROM page WHERE page_id=$profile_id"); // FQL, no {curly_brackets} drupal_set_message(t('The tab settings for %page have been updated.', array( '!url' => $data[0]['page_url'], '%page' => $data[0]['name'], ))); } } /* * Store configuration data for a tab by application. */ function fb_tab_write_config(&$row) { if (!isset($row['created'])) $row['created'] = time(); $row['data'] = serialize($row['data']); return drupal_write_record('fb_tab', $row, isset($row['fb_tab_id']) ? array('fb_tab_id') : NULL); } /* * Return configuration of a tab by application (access via 'label') and page ID. * Page ID exists because an app can present different views on different pages. */ function fb_tab_fetch_config($fb_app, $profile_id) { $row = db_query("SELECT * FROM {fb_tab} WHERE label = :label AND profile_id = :pid", array(':label' => $fb_app->label, ':pid' => $profile_id))->fetchAssoc(); if ($row) { $row['data'] = unserialize($row['data']); return $row; } else { return array(); } } /** * This page callback will show the user a list of pages they have authority to configure. */ function fb_tab_pages() { if ($fbu = fb_facebook_user()) { $result = fb_fql_query($GLOBALS['_fb'], "SELECT page_id, name, pic_small, page_url, type FROM page WHERE has_added_app=1 AND page_id IN (SELECT page_id FROM page_admin WHERE uid=$fbu)"); // FQL, no {curly_brackets} //dpm($result, __FUNCTION__); if (count($result)) { $output['pages'] = array( '#prefix' => '
', '#suffix' => '
', ); } else { $output['intro'] = array( '#value' => t('Found no pages to configure.'), '#prefix' => '', '#suffix' => '
', ); } return drupal_render($output); } else { fb_access_denied(); } } /** * Provides the URL of the settings page for a given facebook page. */ function fb_tab_config_url($profile_id = NULL, $options = array()) { if (!$profile_id) { $profile_id = fb_settings(FB_SETTINGS_PROFILE_ID); } return url(FB_TAB_PATH_FORM . '/' . $profile_id, $options); }