label . ($fb_app->status ? '' : ' ' . t('(not enabled)')); // About. $row[] = l(isset($fb_app->application_name) ? $fb_app->application_name : $fb_app->label, $protocol . '://www.facebook.com/apps/application.php?id=' . $fb_app->id); // Canvas Page. if (isset($fb_app->canvas_name) && $fb_app->canvas_name != $fb_app->canvas) { drupal_set_message(t('Canvas page for %label is out of sync! Facebook believes it is %fbcanvas, while our database believes %canvas. Edit and save the application to remedy this.', array('%label' => $fb_app->label, '%fbcanvas' => $fb_app->canvas_name, '%canvas' => $fb_app->canvas)), 'error'); } if ($fb_app->canvas) { $row[] = l($fb_app->canvas, $protocol . '://apps.facebook.com/' . $fb_app->canvas); } else { $row[] = t('n/a'); } // Local Ops $local_links = fb_invoke(FB_ADMIN_OP_LOCAL_LINKS, array('fb_app' => $fb_app), array(t('view') => FB_PATH_ADMIN_APPS . '/' . $fb_app->label, t('sync props') => FB_PATH_ADMIN_APPS . '/' . $fb_app->label . '/fb/set_props', ), FB_ADMIN_HOOK); $links = array(); foreach ($local_links as $title => $href) { $links[] = array( 'title' => $title, 'href' => $href, ); } $row[] = theme('links', $links); // Remote Settings $row[] = l($fb_app->id, 'https://www.facebook.com/developers/editapp.php?app_id=' . $fb_app->id); $rows[] = $row; } $output .= theme('table', $header, $rows); } else { $output = t('Start by creating an application.'); if (!module_exists('fb_app')) { $output .= t('Ensure the Facebook Application module is enabled.'); } else { $output .= t('Click Add Application to continue.', array('!url' => url('admin/build/fb/fb_app_create'))); } } return $output; } function fb_admin_app_page($fb_app = NULL) { fb_get_app_data($fb_app); fb_admin_get_app_properties($fb_app); $fb = fb_api_init($fb_app); // @TODO use an actual theme function and make render more appealing. // Hide a couple things... unset($fb_app->secret); unset($fb_app->data); // Warn user if values have changed since last edit. foreach (array('canvas_name' => 'canvas', 'application_name' => 'title') as $prop => $key) { if (isset($fb_app->$prop) && $fb_app->$prop != $fb_app->$key) { drupal_set_message(t("The property %prop has been changed to %value on facebook. Go to the Edit tab, confirm values are correct and hit Save button to syncronize the local values.", array('%prop' => $prop, '%value' => $fb_app->$prop)), 'error'); } } $props_map = array( t('Name') => 'name', t('Label') => 'label', t('ID') => 'id', ); $output = "
\n"; // Render props learned from facebook and stored in $fb_app object. $props_map = fb_invoke(FB_ADMIN_OP_LIST_PROPERTIES, array('fb_app' => $fb_app), $props_map, FB_ADMIN_HOOK); foreach ($props_map as $name => $key) { if (isset($fb_app->$key)) { $output .= "
$name
{$fb_app->$key}
\n"; } } // Render additional properties $output .= '
' . t('Access Token') . '
' . fb_get_token($fb) . "
\n"; $output .= "
\n"; //$output .= '
' . print_r($fb_app, 1) . '
'; // debug return $output; } function fb_admin_page_title($fb_app) { return $fb_app->label; } /** * Get properties from Facebook. Fills in the data that we need to * know by querying facebook. */ function fb_admin_get_app_properties(&$fb_app) { static $cache; static $props_map; if (!isset($cache)) { $cache = array(); // http://wiki.developers.facebook.com/index.php/ApplicationProperties $props_map = array( t('About URL') => 'about_url', t('Application Name') => 'application_name', t('Edit URL') => 'edit_url', ); $props_map = fb_invoke(FB_ADMIN_OP_LIST_PROPERTIES, array('fb_app' => $fb_app), $props_map, FB_ADMIN_HOOK); } if (!isset($cache[$fb_app->id])) { if ($fb = fb_api_init($fb_app)) { try { $props = fb_call_method($fb, 'admin.getAppProperties', array( 'properties' => implode(',', array_values($props_map)), )); $cache[$fb_app->id] = $props; } catch (Exception $e) { fb_log_exception($e, t('Failed to get application properties (%label) from Facebook', array('%label' => $fb_app->label))); } } } else { $props = $cache[$fb_app->id]; } // Update $fb_app with the values we got from facebook api. foreach ($props_map as $key) { if (isset($props[$key])) { $fb_app->$key = $props[$key]; } } } /** * Convenience method to return a list of all known apps, suitable for * form elements. * */ function fb_admin_get_app_options($include_current = FALSE, $key = 'label') { $apps = fb_get_all_apps(); $options = array(); if ($include_current) $options[FB_APP_CURRENT] = t(''); foreach ($apps as $app) { $title = !empty($app->title) ? $app->title : $app->label; if ($key == 'id') { // Still needed? $options[$app->id] = $title; } else { $options[$app->label] = $title; } } return $options; } function fb_admin_set_properties_form(&$form_state, $fb_app) { $form['fba_id'] = array( '#type' => 'value', '#value' => $fb_app->fba_id, ); $props = fb_invoke(FB_ADMIN_OP_SET_PROPERTIES, array('fb_app' => $fb_app), array(), FB_ADMIN_HOOK); $form['#fb_props'] = $props; $form['desc'] = array( '#type' => 'markup', '#value' => t('This will attempt to set the following application properties on facebook.com.'), '#prefix' => '

', '#suffix' => '

', ); // @TODO - beautify display of properties. $form['props'] = array( '#type' => 'markup', '#value' => print_r($props, 1), '#prefix' => '
',
    '#suffix' => '
', ); $form['desc2'] = array( '#type' => 'markup', '#value' => t('Syncing will also update local settings with values learned from facebook (i.e. if you have changed your canvas page).'), '#prefix' => '

', '#suffix' => '

', ); return confirm_form($form, t('Are you sure you set properties for %title?', array('%title' => $fb_app->title)), isset($_GET['destination']) ? $_GET['destination'] : FB_PATH_ADMIN_APPS . '/' . $fb_app->label, t('This action cannot be undone.'), t('Sync Properties'), t('Cancel') ); } /** * Button submit function. Use has clicked delete, send them to confirm page. */ function fb_admin_set_properties_form_submit($form, &$form_state) { $fba_id = $form_state['values']['fba_id']; $fb_app = fb_get_app(array('fba_id' => $fba_id)); $props = $form['#fb_props']; if ($fb_app && count($props)) { if ($fb = fb_api_init($fb_app)) { try { $result = fb_call_method($fb, 'admin.setAppProperties', array( 'properties' => json_encode($props), )); // Success. $form_state['redirect'] = FB_PATH_ADMIN_APPS . '/' . $fb_app->label; drupal_set_message(t('Note that it may take several minutes for property changes to propagate to all facebook servers.')); if (fb_verbose()) { drupal_set_message(t('Set the following properties for %label application:
!props
', array('%label' => $fb_app->label, '!props' => print_r($props, 1)))); watchdog('fb_app', 'Set facebook app properties for %label.', array('%label' => $fb_app->label, ), WATCHDOG_NOTICE, l(t('view apps'), FB_PATH_ADMIN)); } // Update local data with values learned from facebook. fb_admin_get_app_properties($fb_app); if ($fb_app->fba_id && $fb_app->canvas_name && module_exists('fb_app')) { // @TODO - clean this up or move it to fb_app.module. fb.module should have no knowledge of fb_app table. db_query("UPDATE {fb_app} SET canvas='%s' WHERE fba_id = %d", array( $fb_app->canvas_name, $fb_app->fba_id, )); } } catch (Exception $e) { drupal_set_message(t('Failed to set the following properties for %label application. You may need to manually editing remote settings!
!props
', array('%label' => $fb_app->label, '!props' => print_r($props, 1))), 'error'); fb_log_exception($e, t('Failed to set application properties on Facebook')); } } } } /** * Form callback for general settings. */ function fb_admin_settings() { $form = array(); // @TODO would be nice to automatically test whether HTTPS is supported. $form['fb_admin_secure'] = array( '#title' => t('Secure URLs'), '#type' => 'fieldset', '#description' => t('Canvas Pages and Page Tabs require a server that supports SSL encrypted HTTPS. Without HTTPS, those features will only work in "sandbox mode."'), ); $form['fb_admin_secure'][FB_VAR_SECURE_URLS] = array( '#type' => 'radios', '#title' => t('Use Secure URLs'), '#default_value' => variable_get(FB_VAR_SECURE_URLS, FB_SECURE_URLS_SOMETIMES), '#description' => t('This setting affects your applications\' connect_url, callback_url, secure_callback_url, profile_tab_url, and secure_page_tab_url properties.'), '#options' => array( FB_SECURE_URLS_NEVER => t('Never use HTTPS. (I.e. this server does not support it.)'), FB_SECURE_URLS_SOMETIMES => t('Use HTTPS only when Facebook expects a secure URL. (Recommended.)'), FB_SECURE_URLS_ALWAYS => t('Always use HTTPS for both secure urls and also other url callbacks.'), ), ); $form['fb_admin_session'] = array( '#title' => t('Sessions'), '#type' => 'fieldset', '#description' => t('Settings that control authentication and session management when connected to Facebook. These settings are relavant for Apps, but not Social Plugins.', array( '!auth_url' => 'http://developers.facebook.com/docs/authentication/', )), '#collapsible' => TRUE, ); $form['fb_admin_session'][FB_VAR_USE_COOKIE] = array( '#type' => 'checkbox', '#title' => t('Use FB Cookie'), '#default_value' => variable_get(FB_VAR_USE_COOKIE, TRUE), '#description' => t('Tell Facebook\'s libraries to set and honor a cookie when user connects. Makes facebook applications run smoother, but fails when third-party cookies are denied by user\'s browser.'), ); $form['fb_admin_session'][FB_VAR_USE_SESSION] = array( '#type' => 'checkbox', '#title' => t('Store tokens in session'), '#default_value' => variable_get(FB_VAR_USE_SESSION, TRUE), '#description' => t('Store tokens and data needed by facebook\'s libraries in Drupal\'s session. Helps applications work even when third-party cookies are denied.'), ); /* Does not appear to work, disabling... $form['fb_admin_session'][FB_VAR_TRY_TO_SET_COOKIE] = array( '#type' => 'checkbox', '#title' => t('Really set FB Cookie'), '#default_value' => variable_get(FB_VAR_TRY_TO_SET_COOKIE, TRUE), '#description' => t('Try to set the facebook cookie when facebook\'s javascript fails to do so (when third-party cookies are disabled). The format of these cookies is not documented, so this attempt to set the cookie may not always succeed. Check this in addition to the tokens in session box above.'), ); */ $form['fb_admin_session'][FB_VAR_RELOAD_APPEND_HASH] = array( '#type' => 'checkbox', '#title' => t('Append hash on javascript page reload'), '#default_value' => variable_get(FB_VAR_RELOAD_APPEND_HASH, FALSE), '#description' => t('When fb.js reloads (on session change), append a query parameter which serves two purposes. First, it will break through a cache which may be desireable when facebook session changes. Second, it prevents infinite reloads when third-party cookies are not enabled. Enable this if you encounter either of those problems.'), ); $form['fb_admin_languages'] = array( '#title' => t('Languages and Locales'), '#type' => 'fieldset', '#collapsible' => TRUE, ); $form['fb_admin_languages'][FB_VAR_LANGUAGE_OVERRIDE] = array( '#title' => t("Use locale learned from facebook, if available."), '#type' => 'checkbox', '#return_value' => 'override', '#default_value' => variable_get(FB_VAR_LANGUAGE_OVERRIDE, 'override'), '#description' => t('Otherwise, use the mapping below when the local user\'s language is known.'), ); foreach (language_list() as $language) { $form['fb_admin_languages']['fb_language_'. $language->language] = array( '#title' => t("Assigned Facebook's locale to @language", array('@language' => t($language->name))), '#type' => 'select', '#options' => fb_admin_i18n_list(), '#default_value' => fb_admin_i18n_map($language->language), ); } return system_settings_form($form); } /** * Validates the settings form. */ function fb_admin_settings_validate($form, &$form_state) { $values = $form_state['values']; if (!$values[FB_VAR_USE_COOKIE] && !$values[FB_VAR_USE_SESSION]) { form_set_error('fb_admin_session][' . FB_VAR_USE_SESSION, t('You must select either the FB Cookie option, the store token in session option, or both.')); form_set_error('fb_admin_session][' . FB_VAR_USE_COOKIE); } } /* * Returns a list of valid Facebook language codes. * Helper function * see: http://wiki.developers.facebook.com/index.php/Facebook_Locales */ function fb_admin_i18n_list() { return array( 'af_ZA' => t('Afrikaans'), 'sq_AL' => t('Albanian'), 'ar_AR' => t('Arabic'), 'hy_AM' => t('Armenian'), 'ay_BO' => t('Aymara'), 'az_AZ' => t('Azeri'), 'eu_ES' => t('Basque'), 'be_BY' => t('Belarusian'), 'bn_IN' => t('Bengali'), 'bs_BA' => t('Bosnian'), 'bg_BG' => t('Bulgarian'), 'ca_ES' => t('Catalan'), 'ck_US' => t('Cherokee'), 'hr_HR' => t('Croatian'), 'cs_CZ' => t('Czech'), 'da_DK' => t('Danish'), 'nl_NL' => t('Dutch'), 'nl_BE' => t('Dutch (België)'), 'en_PI' => t('English (Pirate)'), 'en_GB' => t('English (UK)'), 'en_US' => t('English (US)'), 'en_UD' => t('English (Upside Down)'), 'eo_EO' => t('Esperanto'), 'et_EE' => t('Estonian'), 'fo_FO' => t('Faroese'), 'tl_PH' => t('Filipino'), 'fi_FI' => t('Finnish'), 'fb_FI' => t('Finnish (test)'), 'fr_FR' => t('French (France)'), 'fr_CA' => t('French (Canada)'), 'gl_ES' => t('Galician'), 'ka_GE' => t('Georgian'), 'de_DE' => t('German'), 'el_GR' => t('Greek'), 'gn_PY' => t('Guaraní'), 'gu_IN' => t('Gujarati'), 'he_IL' => t('Hebrew'), 'hi_IN' => t('Hindi'), 'hu_HU' => t('Hungarian'), 'is_IS' => t('Icelandic'), 'id_ID' => t('Indonesian'), 'ga_IE' => t('Irish'), 'it_IT' => t('Italian'), 'ja_JP' => t('Japanese'), 'jv_ID' => t('Javanese'), 'kn_IN' => t('Kannada'), 'kk_KZ' => t('Kazakh'), 'km_KH' => t('Khmer'), 'tl_ST' => t('Klingon'), 'ko_KR' => t('Korean'), 'ku_TR' => t('Kurdish'), 'la_VA' => t('Latin'), 'lv_LV' => t('Latvian'), 'fb_LT' => t('Leet Speak'), 'li_NL' => t('Limburgish'), 'lt_LT' => t('Lithuanian'), 'mk_MK' => t('Macedonian'), 'mg_MG' => t('Malagasy'), 'ms_MY' => t('Malay'), 'ml_IN' => t('Malayalam'), 'mt_MT' => t('Maltese'), 'mr_IN' => t('Marathi'), 'mn_MN' => t('Mongolian'), 'ne_NP' => t('Nepali'), 'se_NO' => t('Northern Sámi'), 'nb_NO' => t('Norwegian (bokmal)'), 'nn_NO' => t('Norwegian (nynorsk)'), 'ps_AF' => t('Pashto'), 'fa_IR' => t('Persian'), 'pl_PL' => t('Polish'), 'pt_PT' => t('Portuguese (Portugal)'), 'pt_BR' => t('Portuguese (Brazil)'), 'pa_IN' => t('Punjabi'), 'qu_PE' => t('Quechua'), 'ro_RO' => t('Romanian'), 'rm_CH' => t('Romansh'), 'ru_RU' => t('Russian'), 'sa_IN' => t('Sanskrit'), 'sr_RS' => t('Serbian'), 'zh_CN' => t('Simplified Chinese (China)'), 'sk_SK' => t('Slovak'), 'sl_SI' => t('Slovenian'), 'so_SO' => t('Somali'), 'es_LA' => t('Spanish'), 'es_CL' => t('Spanish (Chile)'), 'es_CO' => t('Spanish (Colombia)'), 'es_MX' => t('Spanish (Mexico)'), 'es_ES' => t('Spanish (Spain)'), 'es_VE' => t('Spanish (Venezuela)'), 'sw_KE' => t('Swahili'), 'sv_SE' => t('Swedish'), 'sy_SY' => t('Syriac'), 'tg_TJ' => t('Tajik'), 'ta_IN' => t('Tamil'), 'tt_RU' => t('Tatar'), 'te_IN' => t('Telugu'), 'th_TH' => t('Thai'), 'zh_HK' => t('Traditional Chinese (Hong Kong)'), 'zh_TW' => t('Traditional Chinese (Taiwan)'), 'tr_TR' => t('Turkish'), 'uk_UA' => t('Ukrainian'), 'ur_PK' => t('Urdu'), 'uz_UZ' => t('Uzbek'), 'vi_VN' => t('Vietnamese'), 'cy_GB' => t('Welsh'), 'xh_ZA' => t('Xhosa'), 'yi_DE' => t('Yiddish'), 'zu_ZA' => t('Zulu'), ); } /* * Mapping Drupal language code -> Facebook locale * Helper function */ function fb_admin_i18n_map($lang_code) { $languages_map = array( 'af' => 'af_ZA', 'ar' => 'ar_AR', 'ay' => 'ay_BO', 'az' => 'az_AZ', 'be' => 'be_BY', 'bg' => 'bg_BG', 'bn' => 'bn_IN', 'bs' => 'bs_BA', 'ca' => 'ca_ES', 'cs' => 'cs_CZ', 'cy' => 'cy_GB', 'da' => 'da_DK', 'de' => 'de_DE', 'el' => 'el_GR', 'en' => 'en_US', 'eo' => 'eo_EO', 'es' => 'es_ES', 'et' => 'et_EE', 'eu' => 'eu_ES', 'fa' => 'fa_IR', 'fi' => 'fi_FI', 'fo' => 'fo_FO', 'fr' => 'fr_FR', 'ga' => 'ga_IE', 'gl' => 'gl_ES', 'gn' => 'gn_PY', 'gu' => 'gu_IN', 'he' => 'he_IL', 'hi' => 'hi_IN', 'hr' => 'hr_HR', 'hu' => 'hu_HU', 'hy' => 'hy_AM', 'id' => 'id_ID', 'is' => 'is_IS', 'it' => 'it_IT', 'ja' => 'ja_JP', 'jv' => 'jv_ID', 'ka' => 'ka_GE', 'kk' => 'kk_KZ', 'km' => 'km_KH', 'kn' => 'kn_IN', 'ko' => 'ko_KR', 'ku' => 'ku_TR', 'la' => 'la_VA', 'lt' => 'lt_LT', 'lv' => 'lv_LV', 'mg' => 'mg_MG', 'mk' => 'mk_MK', 'ml' => 'ml_IN', 'mn' => 'mn_MN', 'mr' => 'mr_IN', 'ms' => 'ms_MY', 'mt' => 'mt_MT', 'nb' => 'nb_NO', 'ne' => 'ne_NP', 'nl' => 'nl_BE', 'nn' => 'nn_NO', 'pa' => 'pa_IN', 'pl' => 'pl_PL', 'ps' => 'ps_AF', 'qu' => 'qu_PE', 'rm' => 'rm_CH', 'ro' => 'ro_RO', 'ru' => 'ru_RU', 'sa' => 'sa_IN', 'se' => 'se_NO', 'sk' => 'sk_SK', 'sl' => 'sl_SI', 'so' => 'so_SO', 'sq' => 'sq_AL', 'sr' => 'sr_RS', 'sv' => 'sv_SE', 'sw' => 'sw_KE', 'ta' => 'ta_IN', 'te' => 'te_IN', 'tg' => 'tg_TJ', 'th' => 'th_TH', 'tl' => 'tl_ST', 'tr' => 'tr_TR', 'tt' => 'tt_RU', 'uk' => 'uk_UA', 'ur' => 'ur_PK', 'uz' => 'uz_UZ', 'vi' => 'vi_VN', 'xh' => 'xh_ZA', 'yi' => 'yi_DE', 'zh-hans' => 'zh_CN', 'zh-hant' => 'zh_TW', 'zu' => 'zu_ZA', ); return isset($languages_map[$lang_code]) ? $languages_map[$lang_code] : 'en_US'; }