WordPress.org

Plugin Directory

Changeset 624328


Ignore:
Timestamp:
11/13/12 00:18:46 (17 months ago)
Author:
niallkennedy
Message:

version 1.1. custom post types, custom post statuses, individual settings pages, Facebook PHP SDK 3.2, async JS loader, and more

Location:
facebook/trunk
Files:
85 added
19 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • facebook/trunk/facebook.php

    r571850 r624328  
    22/** 
    33 * @package Facebook 
    4  * @version 1.0.2 
     4 * @version 1.1 
    55 */ 
    66/* 
     
    1010Author: Facebook 
    1111Author URI: https://developers.facebook.com/wordpress/ 
    12 Version: 1.0.2 
     12Version: 1.1 
    1313License: GPL2 
    1414License URI: license.txt 
    15 Domain Path: /lang/ 
     15Domain Path: /languages/ 
    1616*/ 
    1717 
    18 global $fb_ver; 
    19 $fb_ver = '1.0.2'; 
    20  
    21 $facebook_plugin_directory = dirname(__FILE__); 
    22  
    23 // Load the textdomain for translations 
    24 add_action('init', 'fb_load_textdomain'); 
    25 function fb_load_textdomain() { 
    26     load_plugin_textdomain( 'facebook', false, dirname( plugin_basename( __FILE__ ) ) . '/lang/' ); 
     18/** 
     19 * Load the Facebook plugin 
     20 * 
     21 * @since 1.1 
     22 */ 
     23class Facebook_Loader { 
     24    /** 
     25     * Uniquely identify plugin version 
     26     * Bust caches based on this value 
     27     * 
     28     * @since 1.1 
     29     * @var string 
     30     */ 
     31    const VERSION = '1.1'; 
     32 
     33    /** 
     34     * Locale of the site expressed as a Facebook locale 
     35     * 
     36     * @since 1.1 
     37     * @var string 
     38     */ 
     39    public $locale = 'en_US'; 
     40 
     41    /** 
     42     * Store Facebook application information (id, secret, namespace) if available. 
     43     * 
     44     * @since 1.1 
     45     * @var array 
     46     */ 
     47    public $credentials = array(); 
     48 
     49    /** 
     50     * List of locales supported by Facebook. 
     51     * Two-letter languages codes stored in WordPress are translated to full locales; if a language has multiple country localizations place the first choice earlier in the array to make it the language default 
     52     * 
     53     * @since 1.1 
     54     */ 
     55    public static $locales = array( 'af_ZA' => true, 'ar_AR' => true, 'ay_BO' => true, 'az_AZ' => true, 'be_BY' => true, 'bg_BG' => true, 'bn_IN' => true, 'bs_BA' => true, 'ca_ES' => true, 'ck_US' => true, 'cs_CZ' => true, 'cy_GB' => true, 'da_DK' => true, 'de_DE' => true, 'el_GR' => true, 'en_US' => true, 'en_GB' => true, 'eo_EO' => true, 'es_CL' => true, 'es_ES' => true, 'es_CO' => true, 'es_LA' => true, 'es_MX' => true, 'es_VE' => true, 'et_EE' => true, 'eu_ES' => true, 'fa_IR' => true, 'fb_FI' => true, 'fb_LT' => true, 'fi_FI' => true, 'fo_FO' => true, 'fr_FR' => true, 'fr_CA' => true, 'ga_IE' => true, 'gl_ES' => true, 'gn_PY' => true, 'gu_IN' => true, 'he_IL' => true, 'hi_IN' => true, 'hr_HR' => true, 'hu_HU' => true, 'hy_AM' => true, 'id_ID' => true, 'is_IS' => true, 'it_IT' => true, 'ja_JP' => true, 'jv_ID' => true, 'ka_GE' => true, 'kk_KZ' => true, 'km_KH' => true, 'kn_IN' => true, 'ko_KR' => true, 'ku_TR' => true, 'la_VA' => true, 'li_NL' => true, 'lt_LT' => true, 'lv_LV' => true, 'mg_MG' => true, 'mk_MK' => true, 'ml_IN' => true, 'mn_MN' => true, 'mr_IN' => true, 'ms_MY' => true, 'mt_MT' => true, 'nb_NO' => true, 'ne_NP' => true, 'nl_NL' => true, 'nl_BE' => true, 'nn_NO' => true, 'pa_IN' => true, 'pl_PL' => true, 'ps_AF' => true, 'pt_PT' => true, 'pt_BR' => true, 'qu_PE' => true, 'rm_CH' => true, 'ro_RO' => true, 'ru_RU' => true, 'sa_IN' => true, 'se_NO' => true, 'sk_SK' => true, 'sl_SI' => true, 'so_SO' => true, 'sq_AL' => true, 'sr_RS' => true, 'sv_SE' => true, 'sw_KE' => true, 'sy_SY' => true, 'ta_IN' => true, 'te_IN' => true, 'tg_TJ' => true, 'th_TH' => true, 'tl_PH' => true, 'tl_ST' => true, 'tr_TR' => true, 'tt_RU' => true, 'uk_UA' => true, 'ur_PK' => true, 'uz_UZ' => true, 'vi_VN' => true, 'xh_ZA' => true, 'yi_DE' => true, 'zh_CN' => true, 'zh_HK' => true, 'zh_TW' => true, 'zu_ZA' => true ); 
     56 
     57    /** 
     58     * Let's get it started 
     59     * 
     60     * @since 1.1 
     61     */ 
     62    public function __construct() { 
     63        // load plugin files relative to this directory 
     64        $this->plugin_directory = dirname(__FILE__) . '/'; 
     65        $this->set_locale(); 
     66 
     67        // Load the textdomain for translations 
     68        load_plugin_textdomain( 'facebook', false, $this->plugin_directory . 'languages/' ); 
     69 
     70        $credentials = get_option( 'facebook_application' ); 
     71        if ( ! is_array( $credentials ) ) 
     72            $credentials = array(); 
     73        $this->credentials = $credentials; 
     74        unset( $credentials ); 
     75 
     76        add_action( 'widgets_init', array( &$this, 'widgets_init' ) ); 
     77 
     78        if ( is_user_logged_in() ) { 
     79            // admin bar may show on public-facing site as well as administrative section 
     80            add_action( 'add_admin_bar_menus', array( &$this, 'admin_bar' ) ); 
     81        } 
     82         
     83 
     84        if ( is_admin() ) { 
     85            add_action( 'admin_enqueue_scripts', array( &$this, 'register_js_sdk' ), 1 ); 
     86            $this->admin_init(); 
     87        } else { 
     88            add_action( 'wp_enqueue_scripts', array( &$this, 'register_js_sdk' ), 1 ); 
     89            add_action( 'wp', array( &$this, 'public_init' ) ); 
     90        } 
     91    } 
     92 
     93    /** 
     94     * Add Facebook functionality to the WordPress admin bar 
     95     * 
     96     * @since 1.1 
     97     * @param WP_Admin_Bar $wp_admin_bar existing WordPress admin bar object 
     98     */ 
     99    public function admin_bar() { 
     100        if ( isset( $this->credentials ) && isset( $this->credentials['app_id'] ) ) { 
     101            if ( get_option( 'facebook_comments_enabled' ) ) { 
     102                if ( ! class_exists( 'Facebook_Comments' ) ) 
     103                    require_once( $this->plugin_directory . 'social-plugins/class-facebook-comments.php' ); 
     104                Facebook_Comments::admin_bar_menu(); 
     105            } 
     106        } 
     107    } 
     108 
     109    /** 
     110     * Register the Facebook JavaScript SDK for later enqueueing 
     111     * 
     112     * @since 1.1 
     113     * @uses wp_register_script 
     114     */ 
     115    public function register_js_sdk() { 
     116        global $wp_scripts; 
     117 
     118        $handle = 'facebook-jssdk'; // match the Facebook async snippet ID to avoid double load 
     119        wp_register_script( $handle, ( is_ssl() ? 'https' : 'http' ) . '://connect.facebook.net/' . $this->locale . '/' . ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? 'all/debug.js' : 'all.js' ), array(), null, true ); 
     120 
     121        // register the script but take it back with an async load 
     122        add_filter( 'script_loader_src', array( &$this, 'async_script_loader_src' ), 1, 2 ); 
     123 
     124        $args = array( 
     125            'channelUrl' => plugins_url( 'channel.php', __FILE__ ), 
     126            'status' => true, 
     127            'cookie' => true, 
     128            'xfbml' => true 
     129        ); 
     130 
     131        // appId optional 
     132        if ( ! empty( $this->credentials['app_id'] ) ) 
     133            $args['appId'] = $this->credentials['app_id']; 
     134 
     135        $args = apply_filters( 'facebook_jssdk_init_options', $args ); 
     136 
     137        // allow the publisher to short circuit the init through the filter 
     138        if ( ! empty( $args ) && isset( $wp_scripts ) ) { 
     139            $wp_scripts->add_data( $handle, 'data', 'window.fbAsyncInit=function(){FB.init(' . json_encode( $args ) . ');' . apply_filters( 'facebook_jssdk_init_extras', '', isset( $this->credentials['app_id'] ) ? $this->credentials['app_id'] : '' ) . '}' ); 
     140        } 
     141    } 
     142 
     143    /** 
     144     * Load Facebook JS SDK async 
     145     * Called from script_loader_src filter 
     146     * 
     147     * @since 1.1 
     148     * @param string $src script URL 
     149     * @param string $handle WordPress registered script handle 
     150     * @return string empty string if Facebook JavaScript SDK, else give back the src variable 
     151     */ 
     152    public function async_script_loader_src( $src, $handle ) { 
     153        if ( $handle !== 'facebook-jssdk' ) 
     154            return $src; 
     155 
     156        // @link https://developers.facebook.com/docs/reference/javascript/#loading 
     157        echo '<div id="fb-root"></div><script type="text/javascript">(function(d){var js,id="facebook-jssdk",ref=d.getElementsByTagName("script")[0];if(d.getElementById(id)){return;}js=d.createElement("script");js.id=id;js.async=true;js.src=' . json_encode( $src ) . ';ref.parentNode.insertBefore(js,ref);}(document));</script>'; 
     158 
     159        // empty out the src response 
     160        // results in extra DOM but nothing to load 
     161        return ''; 
     162    } 
     163 
     164    /** 
     165     * Styles applied to public-facing pages 
     166     * 
     167     * @since 1.1 
     168     * @uses enqueue_styles() 
     169     */ 
     170    public static function enqueue_styles() { 
     171        wp_enqueue_style( 'facebook', plugins_url( 'static/css/style' . ( defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min' ) . '.css', __FILE__ ), array(), self::VERSION ); 
     172    } 
     173 
     174    /** 
     175     * Initialize a global $facebook variable if one does not already exist and credentials stored for this site 
     176     * 
     177     * @since 1.1 
     178     * @return true if $facebook global exists, else false 
     179     */ 
     180    public function load_php_sdk() { 
     181        global $facebook; 
     182 
     183        if ( isset( $facebook ) ) 
     184            return true; 
     185 
     186        if ( ! empty( $this->credentials['app_id'] ) && ! empty( $this->credentials['app_secret'] ) ) { 
     187            if ( ! class_exists( 'Facebook_WP_Extend' ) ) 
     188                require_once( $this->plugin_directory . 'includes/facebook-php-sdk/class-facebook-wp.php' ); 
     189 
     190            $facebook = new Facebook_WP_Extend( array( 
     191                'appId' => $this->credentials['app_id'], 
     192                'secret' => $this->credentials['app_secret'] 
     193            ) ); 
     194            return true; 
     195        } 
     196 
     197        return false; 
     198    } 
     199 
     200    /** 
     201     * Intialize the public, front end views 
     202     * 
     203     * @since 1.1 
     204     */ 
     205    public function public_init() { 
     206        // no feed filters yet 
     207        if ( is_feed() || is_404() ) 
     208            return; 
     209 
     210        // always include Open Graph protocol markup 
     211        if ( ! class_exists( 'Facebook_Open_Graph_Protocol' ) ) 
     212            require_once( $this->plugin_directory . 'open-graph-protocol.php' ); 
     213        add_action( 'wp_head', 'Facebook_Open_Graph_Protocol::add_og_protocol' ); 
     214 
     215        add_action( 'wp_enqueue_scripts', 'Facebook_Loader::enqueue_jssdk' ); 
     216 
     217        $enabled_features = array(); 
     218        $option_name = 'facebook_%s_features'; 
     219        if ( is_home() || is_front_page() ) { 
     220            $enabled_features = get_option( sprintf( $option_name, 'home' ) ); 
     221        } else if ( is_archive() ) { 
     222            // all archives wrapped in one option 
     223            // is_post_type_archive || is_date || is_author || is_category || is_tag || is_tax 
     224            $enabled_features = get_option( sprintf( $option_name, 'archive' ) ); 
     225        } else { 
     226            $post_type = get_post_type(); 
     227            if ( $post_type ) 
     228                $enabled_features = get_option( sprintf( $option_name, $post_type ) ); 
     229        } 
     230        if ( ! is_array( $enabled_features ) || empty( $enabled_features ) ) 
     231            return; 
     232 
     233        require_once( $this->plugin_directory . 'social-plugins/social-plugins.php' ); 
     234 
     235        $priority = apply_filters( 'facebook_content_filter_priority', 30 ); 
     236 
     237        // features available for archives and singular 
     238        if ( isset( $enabled_features['like'] ) ) 
     239            add_filter( 'the_content', 'facebook_the_content_like_button', $priority ); 
     240        if ( isset( $enabled_features['send'] ) ) 
     241            add_filter( 'the_content', 'facebook_the_content_send_button', $priority ); 
     242        if ( isset( $enabled_features['subscribe'] ) ) 
     243            add_filter( 'the_content', 'facebook_the_content_subscribe_button', $priority ); 
     244        if ( isset( $enabled_features['mentions'] ) ) { 
     245            if ( ! function_exists( 'fb_social_publisher_mentioning_output' ) ) 
     246                require_once( dirname(__FILE__) . '/social-publisher/mentions.php' ); 
     247            add_filter( 'the_content', 'fb_social_publisher_mentioning_output', $priority ); 
     248        } 
     249 
     250        // individual posts, pages, and custom post types features 
     251        if ( isset( $post_type ) ) { 
     252            if ( isset( $enabled_features['recommendations_bar'] ) ) 
     253                add_filter( 'the_content', 'facebook_the_content_recommendations_bar', $priority ); 
     254 
     255            // only load comments class and features if enabled and post type supports 
     256            if ( isset( $enabled_features['comments'] ) && post_type_supports( $post_type, 'comments' ) ) { 
     257                if ( ! class_exists( 'Facebook_Comments' ) ) 
     258                    require_once( $this->plugin_directory . 'social-plugins/class-facebook-comments.php' ); 
     259 
     260                add_filter( 'the_content', 'Facebook_Comments::the_content_comments_box', $priority ); 
     261                add_action( 'wp_enqueue_scripts', 'Facebook_Comments::css_hide_comments', 0 ); 
     262                add_filter( 'comments_array', '__return_null' ); 
     263                add_filter( 'comments_open', '__return_true' ); // comments are always open 
     264 
     265                // display comments number if used in template 
     266                add_filter( 'comments_number', 'Facebook_Comments::comments_count_xfbml' ); 
     267 
     268                // short-circuit special template behavior for comment count = 0 
     269                // prevents linking to #respond anchor which leads nowhere 
     270                add_filter( 'get_comments_number', create_function('', 'return -1;') ); 
     271            } 
     272        } 
     273 
     274        add_action( 'wp_enqueue_scripts', 'Facebook_Loader::enqueue_styles' ); 
     275    } 
     276 
     277    /** 
     278     * Enqueue the JavaScript SDK 
     279     * 
     280     * @since 1.1 
     281     * @uses wp_enqueue_script() 
     282     */ 
     283    public static function enqueue_jssdk() { 
     284        wp_enqueue_script( 'facebook-jssdk', false, array(), false, true ); 
     285    } 
     286 
     287    /** 
     288     * Initialize the backend, administrative views 
     289     * 
     290     * @since 1.1 
     291     */ 
     292    public function admin_init() { 
     293        $admin_dir = $this->plugin_directory . 'admin/'; 
     294 
     295        $sdk = $this->load_php_sdk(); 
     296 
     297        if ( $sdk ) { 
     298            if ( ! class_exists( 'Facebook_User' ) ) 
     299                require_once( dirname(__FILE__) . '/facebook-user.php' ); 
     300            Facebook_User::extend_access_token(); 
     301        } 
     302 
     303        if ( ! class_exists( 'Facebook_Settings' ) ) 
     304            require_once( $admin_dir . 'settings.php' ); 
     305        Facebook_Settings::init(); 
     306 
     307        if ( ! class_exists( 'Facebook_Social_Publisher' ) ) 
     308            require_once( $admin_dir . 'social-publisher/social-publisher.php' ); 
     309        new Facebook_Social_Publisher(); 
     310 
     311        if ( ! class_exists( 'Facebook_Mentions_Search' ) ) 
     312            require_once( $admin_dir . 'social-publisher/mentions/mentions-search.php' ); 
     313        Facebook_Mentions_Search::wp_ajax_handlers(); 
     314    } 
     315 
     316    /** 
     317     * Register available widgets 
     318     * 
     319     * @since 1.1 
     320     * @uses register_widget() 
     321     */ 
     322    public function widgets_init() { 
     323        $widget_directory = $this->plugin_directory . 'social-plugins/widgets/'; 
     324 
     325        foreach ( array( 
     326            'like-button' => 'Facebook_Like_Button_Widget', 
     327            'send-button' => 'Facebook_Send_Button_Widget', 
     328            'subscribe-button' => 'Facebook_Subscribe_Button_Widget', 
     329            'recommendations-box' => 'Facebook_Recommendations_Widget', 
     330            'activity-feed' => 'Facebook_Activity_Feed_Widget' 
     331        ) as $filename => $classname ) { 
     332            include_once( $widget_directory . $filename . '.php' ); 
     333            register_widget( $classname ); 
     334        } 
     335    } 
     336 
     337    /** 
     338     * Map the site locale to a supported Facebook locale 
     339     * Affects OGP and SDK outputs 
     340     * 
     341     * @since 1.1 
     342     */ 
     343    public function set_locale() { 
     344        $transient_key = 'facebook_locale'; 
     345        $locale = get_transient( $transient_key ); 
     346        if ( $locale ) { 
     347            $this->locale = $locale; 
     348            return; 
     349        } 
     350 
     351        $locale = str_replace( '-', '_', get_locale() ); 
     352 
     353        // convert locales like "es" to "es_ES" 
     354        if ( strlen( $locale ) === 2 ) { 
     355            $locale = strtolower( $locale ); 
     356            foreach( self::$locales as $facebook_locale => $exists ) { 
     357                if ( substr_compare( $facebook_locale, $locale, 0, 2 ) === 0 ) { 
     358                    $locale = $facebook_locale; 
     359                    break; 
     360                } 
     361            } 
     362        } 
     363 
     364        // check to see if the locale is a valid FB one, if not, use en_US as a fallback 
     365        if ( ! isset( self::$locales[$locale] ) ) { 
     366            $locale = 'en_US'; 
     367        } 
     368 
     369        $locale = apply_filters( 'fb_locale', $locale ); // filter the locale in case somebody has a weird case and needs to change it 
     370        if ( $locale ) { 
     371            set_transient( $transient_key, $locale, 60*60*24 ); 
     372            $this->locale = $locale; 
     373        } 
     374    } 
    27375} 
    28376 
    29 // include the Facebook PHP SDK 
    30 if ( ! class_exists( 'Facebook_WP' ) ) 
    31     require_once( $facebook_plugin_directory . '/includes/facebook-php-sdk/class-facebook-wp.php' ); 
    32  
    33 require_once( $facebook_plugin_directory . '/fb-core.php' ); 
    34 require_once( $facebook_plugin_directory . '/fb-admin-menu.php'); 
    35 require_once( $facebook_plugin_directory . '/fb-open-graph.php'); 
    36 require_once( $facebook_plugin_directory . '/social-plugins/fb-social-plugins.php'); 
    37 require_once( $facebook_plugin_directory . '/fb-login.php' ); 
    38 require_once( $facebook_plugin_directory . '/fb-social-publisher.php' ); 
    39 require_once( $facebook_plugin_directory . '/fb-wp-helpers.php' ); 
    40 unset( $facebook_plugin_directory ); 
     377function facebook_loader_init() { 
     378    global $facebook_loader; 
     379 
     380    $facebook_loader = new Facebook_Loader(); 
     381} 
     382add_action( 'init', 'facebook_loader_init', 0 ); // load before widgets_init at 1 
     383 
     384?> 
  • facebook/trunk/includes/facebook-php-sdk/base_facebook.php

    r571850 r624328  
    119119   * Version. 
    120120   */ 
    121   const VERSION = '3.1.1'; 
     121  const VERSION = '3.2.0'; 
     122 
     123  /** 
     124   * Signed Request Algorithm. 
     125   */ 
     126  const SIGNED_REQUEST_ALGORITHM = 'HMAC-SHA256'; 
    122127 
    123128  /** 
     
    135140   */ 
    136141  public static $DOMAIN_MAP = array( 
    137     'api'       => 'https://api.facebook.com/', 
    138     'api_video' => 'https://api-video.facebook.com/', 
    139     'api_read'  => 'https://api-read.facebook.com/', 
    140     'graph'     => 'https://graph.facebook.com/', 
     142    'api'         => 'https://api.facebook.com/', 
     143    'api_video'   => 'https://api-video.facebook.com/', 
     144    'api_read'    => 'https://api-read.facebook.com/', 
     145    'graph'       => 'https://graph.facebook.com/', 
    141146    'graph_video' => 'https://graph-video.facebook.com/', 
    142     'www'       => 'https://www.facebook.com/', 
     147    'www'         => 'https://www.facebook.com/', 
    143148  ); 
    144149 
     
    188193   */ 
    189194  protected $fileUploadSupport = false; 
     195 
     196  /** 
     197   * Indicates if we trust HTTP_X_FORWARDED_* headers. 
     198   * 
     199   * @var boolean 
     200   */ 
     201  protected $trustForwarded = false; 
    190202 
    191203  /** 
     
    205217      $this->setFileUploadSupport($config['fileUpload']); 
    206218    } 
    207  
     219    if (isset($config['trustForwarded']) && $config['trustForwarded']) { 
     220      $this->trustForwarded = true; 
     221    } 
    208222    $state = $this->getPersistentData('state'); 
    209223    if (!empty($state)) { 
    210       $this->state = $this->getPersistentData('state'); 
     224      $this->state = $state; 
    211225    } 
    212226  } 
     
    273287    return $this->appSecret; 
    274288  } 
    275    
    276   /** 
    277    * Extend an access token, while removing the short-lived token that might have been generated via client-side flow. 
    278    * Thanks to http://stackoverflow.com/questions/486896/adding-a-parameter-to-the-url-with-javascript for the workaround 
     289 
     290  /** 
     291   * Set the file upload support status. 
     292   * 
     293   * @param boolean $fileUploadSupport The file upload support status. 
     294   * @return WP_BaseFacebook 
     295   */ 
     296  public function setFileUploadSupport($fileUploadSupport) { 
     297    $this->fileUploadSupport = $fileUploadSupport; 
     298    return $this; 
     299  } 
     300 
     301  /** 
     302   * Get the file upload support status. 
     303   * 
     304   * @return boolean true if and only if the server supports file upload. 
     305   */ 
     306  public function getFileUploadSupport() { 
     307    return $this->fileUploadSupport; 
     308  } 
     309 
     310  /** 
     311   * DEPRECATED! Please use getFileUploadSupport instead. 
     312   * 
     313   * Get the file upload support status. 
     314   * 
     315   * @return boolean true if and only if the server supports file upload. 
     316   */ 
     317  public function useFileUploadSupport() { 
     318    return $this->getFileUploadSupport(); 
     319  } 
     320 
     321  /** 
     322   * Sets the access token for api calls.  Use this if you get 
     323   * your access token by other means and just want the SDK 
     324   * to use it. 
     325   * 
     326   * @param string $access_token an access token. 
     327   * @return WP_BaseFacebook 
     328   */ 
     329  public function setAccessToken($access_token) { 
     330    $this->accessToken = $access_token; 
     331    return $this; 
     332  } 
     333 
     334  /** 
     335   * Extend an access token, while removing the short-lived token that might 
     336   * have been generated via client-side flow. Thanks to http://bit.ly/b0Pt0H 
     337   * for the workaround. 
    279338   */ 
    280339  public function setExtendedAccessToken() { 
     
    282341      // need to circumvent json_decode by calling _oauthRequest 
    283342      // directly, since response isn't JSON format. 
    284       $access_token_response = 
    285         $this->_oauthRequest( 
    286           $this->getUrl('graph', '/oauth/access_token'), 
    287           $params = array(    'client_id' => $this->getAppId(), 
     343      $access_token_response = $this->_oauthRequest( 
     344        $this->getUrl('graph', '/oauth/access_token'), 
     345        $params = array( 
     346          'client_id' => $this->getAppId(), 
    288347          'client_secret' => $this->getAppSecret(), 
    289           'grant_type'=>'fb_exchange_token', 
    290           'fb_exchange_token'=>$this->getAccessToken(), 
    291         )); 
    292       } catch (WP_FacebookApiException $e) { 
    293         // most likely that user very recently revoked authorization. 
    294         // In any event, we don't have an access token, so say so. 
    295         return false; 
    296       } 
     348          'grant_type' => 'fb_exchange_token', 
     349          'fb_exchange_token' => $this->getAccessToken(), 
     350        ) 
     351      ); 
     352    } 
     353    catch (WP_FacebookApiException $e) { 
     354      // most likely that user very recently revoked authorization. 
     355      // In any event, we don't have an access token, so say so. 
     356      return false; 
     357    } 
    297358   
    298       if (empty($access_token_response)) { 
    299         return false; 
    300       } 
     359    if (empty($access_token_response)) { 
     360      return false; 
     361    } 
    301362       
    302       $response_params = array(); 
    303       parse_str($access_token_response, $response_params); 
    304        
    305       if (!isset($response_params['access_token'])) { 
    306         return false; 
    307       } 
    308        
    309       $this->destroySession(); 
    310        
    311       $this->setPersistentData('access_token', $response_params['access_token']); 
    312   } 
    313  
    314   /** 
    315    * Set the file upload support status. 
    316    * 
    317    * @param boolean $fileUploadSupport The file upload support status. 
    318    * @return WP_BaseFacebook 
    319    */ 
    320   public function setFileUploadSupport($fileUploadSupport) { 
    321     $this->fileUploadSupport = $fileUploadSupport; 
    322     return $this; 
    323   } 
    324  
    325   /** 
    326    * Get the file upload support status. 
    327    * 
    328    * @return boolean true if and only if the server supports file upload. 
    329    */ 
    330   public function getFileUploadSupport() { 
    331     return $this->fileUploadSupport; 
    332   } 
    333  
    334   /** 
    335    * DEPRECATED! Please use getFileUploadSupport instead. 
    336    * 
    337    * Get the file upload support status. 
    338    * 
    339    * @return boolean true if and only if the server supports file upload. 
    340    */ 
    341   public function useFileUploadSupport() { 
    342     return $this->getFileUploadSupport(); 
    343   } 
    344  
    345   /** 
    346    * Sets the access token for api calls.  Use this if you get 
    347    * your access token by other means and just want the SDK 
    348    * to use it. 
    349    * 
    350    * @param string $access_token an access token. 
    351    * @return WP_BaseFacebook 
    352    */ 
    353   public function setAccessToken($access_token) { 
    354     $this->accessToken = $access_token; 
    355     return $this; 
     363    $response_params = array(); 
     364    parse_str($access_token_response, $response_params); 
     365     
     366    if (!isset($response_params['access_token'])) { 
     367      return false; 
     368    } 
     369     
     370    $this->destroySession(); 
     371     
     372    $this->setPersistentData( 
     373      'access_token', $response_params['access_token'] 
     374    ); 
    356375  } 
    357376 
     
    571590      array_merge(array( 
    572591        'next' => $this->getCurrentUrl(), 
    573         'access_token' => $this->getAccessToken(), 
     592        'access_token' => $this->getUserAccessToken(), 
    574593      ), $params) 
    575594    ); 
     
    779798    if (is_array($result) && isset($result['error_code'])) { 
    780799      $this->throwAPIException($result); 
    781     } 
    782  
    783     if ($params['method'] === 'auth.expireSession' || 
    784         $params['method'] === 'auth.revokeAuthorization') { 
     800      // @codeCoverageIgnoreStart 
     801    } 
     802    // @codeCoverageIgnoreEnd 
     803 
     804    $method = strtolower($params['method']); 
     805    if ($method === 'auth.expiresession' || 
     806        $method === 'auth.revokeauthorization') { 
    785807      $this->destroySession(); 
    786808    } 
     
    835857    if (is_array($result) && isset($result['error'])) { 
    836858      $this->throwAPIException($result); 
    837     } 
     859      // @codeCoverageIgnoreStart 
     860    } 
     861    // @codeCoverageIgnoreEnd 
    838862 
    839863    return $result; 
     
    907931                  dirname(__FILE__) . '/fb_ca_chain_bundle.crt'); 
    908932      $result = curl_exec($ch); 
     933    } 
     934 
     935    // With dual stacked DNS responses, it's possible for a server to 
     936    // have IPv6 enabled but not have IPv6 connectivity.  If this is 
     937    // the case, curl will try IPv4 first and if that fails, then it will 
     938    // fall back to IPv6 and the error EHOSTUNREACH is returned by the 
     939    // operating system. 
     940    if ($result === false && empty($opts[CURLOPT_IPRESOLVE])) { 
     941        $matches = array(); 
     942        $regex = '/Failed to connect to ([^:].*): Network is unreachable/'; 
     943        if (preg_match($regex, curl_error($ch), $matches)) { 
     944          if (strlen(@inet_pton($matches[1])) === 16) { 
     945            self::errorLog('Invalid IPv6 configuration on server, '. 
     946                           'Please disable or get native IPv6 on your server.'); 
     947            self::$CURL_OPTS[CURLOPT_IPRESOLVE] = CURL_IPRESOLVE_V4; 
     948            curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); 
     949            $result = curl_exec($ch); 
     950          } 
     951        } 
    909952    } 
    910953 
     
    937980    $data = json_decode(self::base64UrlDecode($payload), true); 
    938981 
    939     if (strtoupper($data['algorithm']) !== 'HMAC-SHA256') { 
    940       self::errorLog('Unknown algorithm. Expected HMAC-SHA256'); 
     982    if (strtoupper($data['algorithm']) !== self::SIGNED_REQUEST_ALGORITHM) { 
     983      self::errorLog( 
     984        'Unknown algorithm. Expected ' . self::SIGNED_REQUEST_ALGORITHM); 
    941985      return null; 
    942986    } 
     
    951995 
    952996    return $data; 
     997  } 
     998 
     999  /** 
     1000   * Makes a signed_request blob using the given data. 
     1001   * 
     1002   * @param array The data array. 
     1003   * @return string The signed request. 
     1004   */ 
     1005  protected function makeSignedRequest($data) { 
     1006    if (!is_array($data)) { 
     1007      throw new InvalidArgumentException( 
     1008        'makeSignedRequest expects an array. Got: ' . print_r($data, true)); 
     1009    } 
     1010    $data['algorithm'] = self::SIGNED_REQUEST_ALGORITHM; 
     1011    $data['issued_at'] = time(); 
     1012    $json = json_encode($data); 
     1013    $b64 = self::base64UrlEncode($json); 
     1014    $raw_sig = hash_hmac('sha256', $b64, $this->getAppSecret(), $raw = true); 
     1015    $sig = self::base64UrlEncode($raw_sig); 
     1016    return $sig.'.'.$b64; 
    9531017  } 
    9541018 
     
    10541118  } 
    10551119 
     1120  protected function getHttpHost() { 
     1121    if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_HOST'])) { 
     1122      return $_SERVER['HTTP_X_FORWARDED_HOST']; 
     1123    } 
     1124    return $_SERVER['HTTP_HOST']; 
     1125  } 
     1126 
     1127  protected function getHttpProtocol() { 
     1128    if ($this->trustForwarded && isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) { 
     1129      if ($_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') { 
     1130        return 'https'; 
     1131      } 
     1132      return 'http'; 
     1133    } 
     1134    if (isset($_SERVER['HTTPS']) && 
     1135        ($_SERVER['HTTPS'] === 'on' || $_SERVER['HTTPS'] == 1)) { 
     1136      return 'https'; 
     1137    } 
     1138    return 'http'; 
     1139  } 
     1140 
     1141  /** 
     1142   * Get the base domain used for the cookie. 
     1143   */ 
     1144  protected function getBaseDomain() { 
     1145    // The base domain is stored in the metadata cookie if not we fallback 
     1146    // to the current hostname 
     1147    $metadata = $this->getMetadataCookie(); 
     1148    if (array_key_exists('base_domain', $metadata) && 
     1149        !empty($metadata['base_domain'])) { 
     1150      return trim($metadata['base_domain'], '.'); 
     1151    } 
     1152    return $this->getHttpHost(); 
     1153  } 
     1154 
     1155  /** 
     1156 
    10561157  /** 
    10571158   * Returns the Current URL, stripping it of known FB parameters that should 
     
    10611162   */ 
    10621163  protected function getCurrentUrl() { 
    1063     if (isset($_SERVER['HTTPS']) && 
    1064         ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || 
    1065         isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && 
    1066         $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { 
    1067       $protocol = 'https://'; 
    1068     } 
    1069     else { 
    1070       $protocol = 'http://'; 
    1071     } 
    1072     $currentUrl = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; 
     1164    $protocol = $this->getHttpProtocol() . '://'; 
     1165    $host = $this->getHttpHost(); 
     1166    $currentUrl = $protocol.$host.$_SERVER['REQUEST_URI']; 
    10731167    $parts = parse_url($currentUrl); 
    10741168 
     
    11611255    // @codeCoverageIgnoreStart 
    11621256    // if (php_sapi_name() != 'cli') { 
    1163       //error_log($msg); 
     1257    //  error_log($msg); 
    11641258    // } 
    11651259    // uncomment this if you want to see the errors on the page 
     
    11731267   *   - instead of + 
    11741268   *   _ instead of / 
     1269   *   No padded = 
    11751270   * 
    11761271   * @param string $input base64UrlEncoded string 
     
    11791274  protected static function base64UrlDecode($input) { 
    11801275    return base64_decode(strtr($input, '-_', '+/')); 
     1276  } 
     1277 
     1278  /** 
     1279   * Base64 encoding that doesn't need to be urlencode()ed. 
     1280   * Exactly the same as base64_encode except it uses 
     1281   *   - instead of + 
     1282   *   _ instead of / 
     1283   * 
     1284   * @param string $input string 
     1285   * @return string base64Url encoded string 
     1286   */ 
     1287  protected static function base64UrlEncode($input) { 
     1288    $str = strtr(base64_encode($input), '+/', '-_'); 
     1289    $str = str_replace('=', '', $str); 
     1290    return $str; 
    11811291  } 
    11821292 
     
    11961306      unset($_COOKIE[$cookie_name]); 
    11971307      if (!headers_sent()) { 
    1198         // The base domain is stored in the metadata cookie if not we fallback 
    1199         // to the current hostname 
    1200         $base_domain = '.'. $_SERVER['HTTP_HOST']; 
    1201  
    1202         $metadata = $this->getMetadataCookie(); 
    1203         if (array_key_exists('base_domain', $metadata) && 
    1204             !empty($metadata['base_domain'])) { 
    1205           $base_domain = $metadata['base_domain']; 
    1206         } 
    1207  
    1208         setcookie($cookie_name, '', 0, '/', $base_domain); 
     1308        $base_domain = $this->getBaseDomain(); 
     1309        setcookie($cookie_name, '', 1, '/', '.'.$base_domain); 
    12091310      } else { 
     1311        // @codeCoverageIgnoreStart 
    12101312        self::errorLog( 
    12111313          'There exists a cookie that we wanted to clear that we couldn\'t '. 
    12121314          'clear because headers was already sent. Make sure to do the first '. 
    1213           'API call before outputing anything' 
     1315          'API call before outputing anything.' 
    12141316        ); 
     1317        // @codeCoverageIgnoreEnd 
    12151318      } 
    12161319    } 
     
    12481351  } 
    12491352 
     1353  protected static function isAllowedDomain($big, $small) { 
     1354    if ($big === $small) { 
     1355      return true; 
     1356    } 
     1357    return self::endsWith($big, '.'.$small); 
     1358  } 
     1359 
     1360  protected static function endsWith($big, $small) { 
     1361    $len = strlen($small); 
     1362    if ($len === 0) { 
     1363      return true; 
     1364    } 
     1365    return substr($big, -$len) === $small; 
     1366  } 
     1367 
    12501368  /** 
    12511369   * Each of the following four methods should be overridden in 
  • facebook/trunk/includes/facebook-php-sdk/class-facebook-wp.php

    r571850 r624328  
    11<?php 
    22 
     3// parent class 
    34if ( ! class_exists( 'WP_Facebook' ) ) 
    45    require_once( dirname( __FILE__ ) . '/facebook.php' ); 
     
    1011 */ 
    1112class Facebook_WP_Extend extends WP_Facebook { 
     13 
    1214    /** 
    1315     * Override Facebook PHP SDK cURL function with WP_HTTP 
     
    2628        if ( empty( $url ) || empty( $params ) ) 
    2729            throw new WP_FacebookApiException( array( 'error_code' => 400, 'error' => array( 'type' => 'makeRequest', 'message' => 'Invalid parameters and/or URI passed to makeRequest' ) ) ); 
    28              
     30 
    2931        $params = array( 
    3032            'redirection' => 0, 
     
    3840 
    3941        $response = wp_remote_post( $url, $params ); 
    40          
     42 
    4143        if ( is_wp_error( $response ) ) { 
    4244            throw new WP_FacebookApiException( array( 'error_code' => $response->get_error_code(), 'error_msg' => $response->get_error_message() ) ); 
    43         } 
    44         else if ( wp_remote_retrieve_response_code( $response ) != '200' ) { 
     45        } else if ( wp_remote_retrieve_response_code( $response ) != '200' ) { 
    4546            $fb_response = json_decode( $response['body'] ); 
    46              
     47 
    4748            $error_subcode = ''; 
    48              
     49 
    4950            if ( isset( $fb_response->error->error_subcode ) ) { 
    5051                $error_subcode = $fb_response->error->error_subcode; 
    5152            } 
    52              
    53             throw new WP_FacebookApiException(array( 
    54         'error_code' => $fb_response->error->code, 
    55         'error' => array( 
    56         'message' => $fb_response->error->message, 
    57         'type' => $fb_response->error->type, 
    58         ), 
    59       )); 
     53 
     54            throw new WP_FacebookApiException( array( 
     55                'error_code' => $fb_response->error->code, 
     56                'error' => array( 
     57                    'message' => $fb_response->error->message, 
     58                    'type' => $fb_response->error->type 
     59                ) 
     60            ) ); 
    6061        } 
    61          
     62 
    6263        return wp_remote_retrieve_body( $response ); 
    6364    } 
    64    
    65   /** 
    66    * Extend an access token, while removing the short-lived token that might have been generated via client-side flow. 
    67    * Thanks to http://stackoverflow.com/questions/486896/adding-a-parameter-to-the-url-with-javascript for the workaround 
    68    */ 
    69   public function setExtendedAccessToken() { 
    70     try { 
    71       // need to circumvent json_decode by calling _oauthRequest 
    72       // directly, since response isn't JSON format. 
    73       $access_token_response = 
    74         $this->_oauthRequest( 
    75           $this->getUrl('graph', '/oauth/access_token'), 
    76           $params = array(    'client_id' => $this->getAppId(), 
    77           'client_secret' => $this->getAppSecret(), 
    78           'grant_type'=>'fb_exchange_token', 
    79           'fb_exchange_token'=>$this->getAccessToken(), 
    80         )); 
    81       } catch (WP_FacebookApiException $e) { 
    82         // most likely that user very recently revoked authorization. 
    83         // In any event, we don't have an access token, so say so. 
    84         return false; 
    85       } 
    86    
    87       if (empty($access_token_response)) { 
    88         return false; 
    89       } 
    90        
    91       $response_params = array(); 
    92       parse_str($access_token_response, $response_params); 
    93        
    94       if (!isset($response_params['access_token'])) { 
    95         return false; 
    96       } 
    97        
    98       $this->destroySession(); 
    99        
    100       $this->setPersistentData('access_token', $response_params['access_token']); 
    101   } 
    10265 
    103   /** 
    104    * Provides the implementations of the inherited abstract 
    105    * methods.  The implementation uses user meta to maintain 
    106    * a store for authorization codes, user ids, CSRF states, and 
    107    * access tokens. 
    108    */ 
    109   protected function setPersistentData($key, $value){ 
    110      
    111         if (!in_array($key, self::$kSupportedKeys)) { 
    112           self::errorLog('Unsupported key passed to setPersistentData.'); 
    113           return;    
    114         } 
    115          
    116         //WP 3.0+ 
    117         fb_update_user_meta( get_current_user_id(), $key, $value); 
     66    /** 
     67     * Request current application permissions for an authenticated Facebook user 
     68     * 
     69     * @since 1.1 
     70     * @return array user permissions as flat array 
     71     */ 
     72    public function get_current_user_permissions( $current_user = '' ) { 
     73        if ( ! $current_user ) { 
     74            // load user functions 
     75            if ( ! class_exists( 'Facebook_User' ) ) 
     76                require_once( dirname( dirname( dirname(__FILE__) ) ) . '/facebook-user.php' ); 
     77 
     78            // simply verify a connection between user and app 
     79            $current_user = Facebook_User::get_current_user( array( 'id' ) ); 
     80            if ( ! $current_user ) 
     81                return array(); 
     82        } 
     83 
     84        try { 
     85            $response = $this->api( '/me/permissions', 'GET', array( 'ref' => 'fbwpp' ) ); 
     86        } catch ( WP_FacebookApiException $e ) { 
     87            $error_result = $e->getResult(); 
     88            if ( $error_result && isset( $error_result['error_code'] ) ) { 
     89                // try to extend access token if request failed 
     90                if ( $error_result['error_code'] === 2500 ) 
     91                    $this->setExtendedAccessToken(); 
     92            } 
     93            return array(); 
     94        } 
     95 
     96        if ( is_array( $response ) && isset( $response['data'][0] ) ) { 
     97            $permissions = array(); 
     98            foreach( $response['data'][0] as $permission => $exists ) { 
     99                $permissions[$permission] = true; 
     100            } 
     101            return $permissions; 
     102        } 
     103 
     104        return array(); 
    118105    } 
    119106 
    120   protected function getPersistentData($key, $default = false){ 
    121      
    122     if (!in_array($key, self::$kSupportedKeys)) { 
    123       self::errorLog('Unsupported key passed to getPersistentData.'); 
    124       return $default; 
    125     } 
    126      
    127       return $usermeta = fb_get_user_meta( get_current_user_id(), $key, true ); 
     107    /** 
     108     * Provides the implementations of the inherited abstract 
     109     * methods.  The implementation uses user meta to maintain 
     110     * a store for authorization codes, user ids, CSRF states, and 
     111     * access tokens. 
     112     */ 
     113    protected function setPersistentData( $key, $value ) { 
     114        if ( ! in_array( $key, self::$kSupportedKeys ) ) { 
     115            self::errorLog('Unsupported key passed to setPersistentData.'); 
     116            return; 
     117        } 
     118 
     119        // load user functions 
     120        if ( ! class_exists( 'Facebook_User' ) ) 
     121            require_once( dirname( dirname( dirname(__FILE__) ) ) . '/facebook-user.php' ); 
     122        Facebook_User::update_user_meta( get_current_user_id(), $key, $value ); 
    128123    } 
    129124 
    130   protected function clearPersistentData($key) { 
    131     if (!in_array($key, self::$kSupportedKeys)) { 
    132       self::errorLog('Unsupported key passed to clearPersistentData.'); 
    133       return; 
    134     } 
     125    protected function getPersistentData( $key, $default = false ) { 
     126        if ( ! in_array( $key, self::$kSupportedKeys ) ) { 
     127            self::errorLog('Unsupported key passed to getPersistentData.'); 
     128            return $default; 
     129        } 
    135130 
    136     fb_delete_user_meta( get_current_user_id(), $key); 
    137   } 
     131        // load user functions 
     132        if ( ! class_exists( 'Facebook_User' ) ) 
     133            require_once( dirname( dirname( dirname(__FILE__) ) ) . '/facebook-user.php' ); 
     134        return Facebook_User::get_user_meta( get_current_user_id(), $key, true ); 
     135    } 
    138136 
    139   protected function clearAllPersistentData() { 
    140     foreach (self::$kSupportedKeys as $key) { 
    141       $this->clearPersistentData($key); 
    142     } 
    143   } 
     137    protected function clearPersistentData($key) { 
     138        if ( ! in_array( $key, self::$kSupportedKeys ) ) { 
     139            self::errorLog('Unsupported key passed to clearPersistentData.'); 
     140            return; 
     141        } 
     142 
     143        // load user functions 
     144        if ( ! class_exists( 'Facebook_User' ) ) 
     145            require_once( dirname( dirname( dirname(__FILE__) ) ) . '/facebook-user.php' ); 
     146        Facebook_User::delete_user_meta( get_current_user_id(), $key ); 
     147    } 
     148 
     149    protected function clearAllPersistentData() { 
     150        foreach ( self::$kSupportedKeys as $key ) { 
     151            $this->clearPersistentData($key); 
     152        } 
     153    } 
    144154} 
    145155?> 
  • facebook/trunk/includes/facebook-php-sdk/facebook.php

    r571850 r624328  
    2626class WP_Facebook extends WP_BaseFacebook 
    2727{ 
     28  const FBSS_COOKIE_NAME = 'fbss'; 
     29 
     30  // We can set this to a high number because the main session 
     31  // expiration will trump this. 
     32  const FBSS_COOKIE_EXPIRE = 31556926; // 1 year 
     33 
     34  // Stores the shared session ID if one is set. 
     35  protected $sharedSessionID; 
     36 
    2837  /** 
    2938   * Identical to the parent constructor, except that 
     
    3241   * we discover them. 
    3342   * 
    34    * @param Array $config the application configuration. 
     43   * @param Array $config the application configuration. Additionally 
     44   * accepts "sharedSession" as a boolean to turn on a secondary 
     45   * cookie for environments with a shared session (that is, your app 
     46   * shares the domain with other apps). 
    3547   * @see WP_BaseFacebook::__construct in facebook.php 
    3648   */ 
    3749  public function __construct($config) { 
    38      
     50    if (!session_id()) { 
     51      session_start(); 
     52    } 
    3953    parent::__construct($config); 
     54    if (!empty($config['sharedSession'])) { 
     55      $this->initSharedSession(); 
     56    } 
    4057  } 
    4158 
    4259  protected static $kSupportedKeys = 
    4360    array('state', 'code', 'access_token', 'user_id'); 
     61 
     62  protected function initSharedSession() { 
     63    $cookie_name = $this->getSharedSessionCookieName(); 
     64    if (isset($_COOKIE[$cookie_name])) { 
     65      $data = $this->parseSignedRequest($_COOKIE[$cookie_name]); 
     66      if ($data && !empty($data['domain']) && 
     67          self::isAllowedDomain($this->getHttpHost(), $data['domain'])) { 
     68        // good case 
     69        $this->sharedSessionID = $data['id']; 
     70        return; 
     71      } 
     72      // ignoring potentially unreachable data 
     73    } 
     74    // evil/corrupt/missing case 
     75    $base_domain = $this->getBaseDomain(); 
     76    $this->sharedSessionID = md5(uniqid(mt_rand(), true)); 
     77    $cookie_value = $this->makeSignedRequest( 
     78      array( 
     79        'domain' => $base_domain, 
     80        'id' => $this->sharedSessionID, 
     81      ) 
     82    ); 
     83    $_COOKIE[$cookie_name] = $cookie_value; 
     84    if (!headers_sent()) { 
     85      $expire = time() + self::FBSS_COOKIE_EXPIRE; 
     86      setcookie($cookie_name, $cookie_value, $expire, '/', '.'.$base_domain); 
     87    } else { 
     88      // @codeCoverageIgnoreStart 
     89      self::errorLog( 
     90        'Shared session ID cookie could not be set! You must ensure you '. 
     91        'create the Facebook instance before headers have been sent. This '. 
     92        'will cause authentication issues after the first request.' 
     93      ); 
     94      // @codeCoverageIgnoreEnd 
     95    } 
     96  } 
    4497 
    4598  /** 
     
    84137      $this->clearPersistentData($key); 
    85138    } 
     139    if ($this->sharedSessionID) { 
     140      $this->deleteSharedSessionCookie(); 
     141    } 
     142  } 
     143 
     144  protected function deleteSharedSessionCookie() { 
     145    $cookie_name = $this->getSharedSessionCookieName(); 
     146    unset($_COOKIE[$cookie_name]); 
     147    $base_domain = $this->getBaseDomain(); 
     148    setcookie($cookie_name, '', 1, '/', '.'.$base_domain); 
     149  } 
     150 
     151  protected function getSharedSessionCookieName() { 
     152    return self::FBSS_COOKIE_NAME . '_' . $this->getAppId(); 
    86153  } 
    87154 
    88155  protected function constructSessionVariableName($key) { 
    89     return implode('_', array('fb', 
    90                               $this->getAppId(), 
    91                               $key)); 
     156    $parts = array('fb', $this->getAppId(), $key); 
     157    if ($this->sharedSessionID) { 
     158      array_unshift($parts, $this->sharedSessionID); 
     159    } 
     160    return implode('_', $parts); 
    92161  } 
    93162} 
  • facebook/trunk/readme.txt

    r571850 r624328  
    11=== Facebook === 
    2 Contributors: Facebook, automattic, mattwkelly, niallkennedy, rgharpuray, ngfeldman, jamesgpearce, ravi.grover, danielbachhuber, gigawats, eosgood, Otto42 
     2Contributors: facebook, automattic, mattwkelly, niallkennedy, rgharpuray, ngfeldman, jamesgpearce, ravi.grover, danielbachhuber, gigawats, eosgood, Otto42, colmdoyle, zazinteractive 
    33Tags: Facebook, comments, social, friends, like, like button, social plugins, facebook platform, page, posts, sidebar, plugin, open graph 
    4 Requires at least: 3.2.1 
    5 Tested up to: 3.4 
    6 Stable tag: trunk 
     4Requires at least: 3.3 
     5Tested up to: 3.5 
     6License: GPLv2 
     7License URI: http://www.gnu.org/licenses/gpl-2.0.html 
     8Stable tag: 1.1 
    79 
    810Make your WordPress site social in a couple of clicks, powered by Facebook. 
     
    1214This WordPress plugin makes your site deeply social by integrating functionality from Facebook. 
    1315 
    14 For more information, check out http://developers.facebook.com/wordpress. 
     16[Facebook Insights](http://www.facebook.com/insights) integration included to help you better understand your site audience with Facebook demographic and sharing data. 
    1517 
    16 **Page and Post Features** 
     18The Facebook plugin for WordPress is internationalization- and mobile-ready. 
    1719 
    18 All of these features are easy to enable via checkboxes on the Facebook settings page. 
     20For more information, check out [the WordPress plugin page on the Facebook Developers site](http://developers.facebook.com/wordpress/). 
    1921 
    20 * Post to an Author's Facebook Timeline whenever they publish a new WordPress Post or Page. 
    21 * Mention friends and Facebook Pages.  This posts to their Timelines as well as lists them on the WordPress Post or Page. 
    22 * Post all new WordPress Post or Pages to a specified Facebook Page. 
    23 * Like, send, and subscribe buttons can be enabled in a click and are fully customizable. 
    24 * Facebook Comments, including full SEO support. 
    25 * Open Graph Protocol integration. 
    26 * Recommendations bar, which allows users to click to start getting recommendations, Like content, and add what they're reading to Timeline as they go. 
     22= Post Features = 
    2723 
    28 **Widgets** 
     24Customize features through post settings. 
    2925 
    30 All of these features are easy to enable via the Widgets settings page. 
     26* Post to an author's Facebook Timeline whenever a post is made public. 
     27* Mention Facebook friends and pages. New posts will be published to the timelines of the mentioned account(s) and displayed alongside the post. 
     28* [Like](https://developers.facebook.com/docs/reference/plugins/like/), [send](https://developers.facebook.com/docs/reference/plugins/send/), and [subscribe](https://developers.facebook.com/docs/reference/plugins/subscribe/) buttons can be easily added to a post to drive social distribution with custom settings scoped to your Facebook application identifier. 
     29* [Facebook Comments Box](https://developers.facebook.com/docs/reference/plugins/comments/) social plugin including noscript fallbacks for easy indexing by search engines. 
     30* [Open Graph protocol](http://ogp.me) integration to help your content stand out in Facebook newsfeed, Twitter Cards, Windows 8 bookmarks, and other consuming agents. 
     31* [Recommendations bar](https://developers.facebook.com/docs/reference/plugins/recommendationsbar/) helps visitors discover more content on your site by recommending other articles and encouraging Like shares. 
    3132 
    32 * Activity Feed Box. This shows the Facebook user the activity that their friends are doing on your website. 
    33 * Recommendations Box.  This shows the Facebook user recommendations of pages they should visit based on the actions their friends are taking on your website. 
    34 * Like, send, and subscribe buttons. 
     33= Widgets = 
    3534 
    36 Facebook Insights (http://www.facebook.com/insights) integration included. This plugin also supports internationalization and mobile. 
     35Add new widgets to one or more sidebars. 
     36 
     37* [Activity Feed Box](https://developers.facebook.com/docs/reference/plugins/activity/) displays recent sharing activity on your site customized for each visitor logged-on to Facebook. 
     38* [Recommendations Box](https://developers.facebook.com/docs/reference/plugins/recommendations/) recommends content based on visitor interests and the sharing activity of his or her Facebook friends. 
     39* [Like](https://developers.facebook.com/docs/reference/plugins/like/), [send](https://developers.facebook.com/docs/reference/plugins/send/), and [subscribe](https://developers.facebook.com/docs/reference/plugins/subscribe/) buttons encourage social engagement. 
     40 
     41= Contributing code = 
     42 
     43All of the [source code for this plugin is available on Facebook's GitHub account](https://github.com/facebook/wordpress). If you like to contribute code to the plugin, open up an issue against the repository where we can discuss it. Once you have completed the code, open [a Pull Request](https://github.com/facebook/wordpress/pulls). 
     44 
     45Note: all contributors must agree to and sign the [Facebook Contributor License Agreement](https://developers.facebook.com/opensource/cla) prior to submitting Pull Requests. We can't accept Pull Requests until this document is signed and submitted, affirming your code is not encumbered by intellectual property claims by yourself or your employer and therefore eligible for redistribution by Facebook under the Freedoms of the GPL. 
    3746 
    3847== Installation == 
     
    53628. Widgets are also available. 
    5463 
     64== Custom actions & filters == 
     65 
     66= Actions = 
     67 
     68* `facebook_notify_plugin_conflicts` - executes code to notify site administrators of possible conflicts with other plugins by iterating through a list of all installed plugins and highlighting known conflicts at the time the Facebook plugin for WordPress was released. Some publishers may wish to remove this check for efficiency. 
     69* `facebook_settings_before_header_$hook_suffix` - add content to a settings page before the main page header section 
     70* `facebook_settings_after_header_$hook_suffix` - add content to a settings page after the main page header section 
     71* `facebook_settings_footer_$hook_suffix` - add content to a settings page below the wrapper div 
     72 
     73= Filters = 
     74 
     75* `facebook_features` - limit the plugin features available on your site 
     76* `fb_conflicting_plugins` - add or remove plugin URLs used by the plugin to warn against potential conflicts 
     77* `facebook_jssdk_init_options` - customize arguments sent to the [FB.init](https://developers.facebook.com/docs/reference/javascript/FB.init/) function of the Facebook JavaScript SDK 
     78* `facebook_jssdk_init_extras` - add extra JavaScript to the `fbAsyncInit` JavaScript function called after the Facebook JavaScript SDK is loaded 
     79* `facebook_content_filter_priority` - choose the priority of Facebook social plugin filters attached to `the_content` filter. Affects where Facebook content is output on your page relative to other plugins attached to `the_content` 
     80* `fb_locale` - directly define your site locale based on the list of [Facebook locale mappings](https://developers.facebook.com/docs/internationalization/) 
     81* `facebook_excerpt_length` - choose a custom length, in words, of a post excerpt generated for use in the Open Graph protocol description. default: 55 
     82* `facebook_excerpt_more` - string appearing at the end of a truncated excerpt string. default: "&hellip;" 
     83* `fb_rel_canonical` - customize the canonical URL used by Facebook for a post. Affects Open Graph protocol URL definitions, URL references sent in Open Graph actions, and more. default: result of `get_permalink()` 
     84* `facebook_comment_schema_org` - override output of search engine friendly comments content using [Schema.org microdata markup](http://googlewebmastercentral.blogspot.com/2011/06/introducing-schemaorg-search-engines.html) 
     85* `facebook_anchor_target` - customize the [browsing context name](http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#browsing-context-names) used for links to Facebook output alongside your post such as mentions. default: `_blank` 
     86* `facebook_mentions_classes` - add or remove HTML classes from the parent HTML div element of mentions links 
     87* `fb_meta_tags` - Customize Open Graph protocol markup before it is output to the page 
     88* `fb_get_user_meta` - fetch a user meta value by attaching to this filter, bypassing the WordPress user meta API 
     89* `fb_update_user_meta` - update a user meta value by attaching to this filter, bypassing the WordPress user meta API 
     90* `fb_delete_user_meta` - delete a user meta value by attaching to this filter, bypassing the WordPress user meta API 
     91 
     92== Frequently Asked Questions == 
     93 
     94= How do I change the image that appears for my posts shared on Facebook = 
     95 
     96The plugin generates [Open Graph protocol](http://ogp.me/) markup for your site's webpages including an explicitly-specified image for posts with an associated [post thumbnail](http://codex.wordpress.org/Post_Thumbnails). Your plugin or theme may define additional images through the `fb_meta_tags` filter. If an post thumbnail image exists your additional image will be an alternate for stories shared through a pasted link. Unattended story summaries use the first defined image. 
     97 
     98= How do I moderate comments and add reviewers? = 
     99 
     100The [Comment Moderation Tool](https://developers.facebook.com/tools/comments) allows you to customize your Facebook application's moderators, blacklisted words, external logins, and more. 
     101 
     102= Does Facebook Comments work with my existing WordPress comments? = 
     103 
     104The [Comments Box social plugin](https://developers.facebook.com/docs/reference/plugins/comments/) is meant to replace the WordPress commenting system with a more social, client-side experience. We do not currently support synchronizing comments stored on Facebook with comments stored in your WordPress database. 
     105 
     106== Upgrade Notice == 
     107 
     108= 1.1 = 
     109Custom post types and status support. Rewritten settings pages. Longer-lived Facebook access tokens. Async JavaScript loading. Threaded comment support. 
     110 
     111= 1.0.2 = 
     112Improve site performance when cURL not installed or SSL not available. Removed post meta boxes when social publishing features not enabled. 
     113 
     114= 1.0.1 = 
     115Security fixes. Improved customization and debugging of settings. l10n and i18n fixes. 
     116 
    55117== Changelog == 
     118 
     119= 1.1 = 
     120 
     121* Supports public [custom post types](http://codex.wordpress.org/Post_Types) and [custom post status](http://codex.wordpress.org/Function_Reference/register_post_status) 
     122* [Facebook JavaScript SDK](https://developers.facebook.com/docs/reference/javascript/) loads asynchronously after pageload 
     123* Settings page broken into multiple settings pages with [WordPress Settings API](http://codex.wordpress.org/Settings_API) support 
     124* Choose to display social plugins and mentions on your homepage, archive pages, or individual post types 
     125* Comments markup appearing in noscript wrappers now include [Schema.org comment markup](http://schema.org/UserComments) by default 
     126* Added threaded comment support for noscript fallback markup 
     127* Updated [Facebook PHP SDK](https://github.com/facebook/facebook-php-sdk/) to version 3.2 
     128* New social plugins builder helps correct mistakes before they happen and only include markup on your pages capable of interpretation by the Facebook JavaScript SDK 
     129* Mention links open in a new browsing context by default 
     130* Post mentions are displayed inside their meta boxes after save 
     131* Strings pass through translation functions, opening up future translation support 
     132* Fixed mixed-content warnings thrown when Facebook images displayed on a page 
     133* Uninstall script removes site and user options when the plugin is uninstalled through the WordPress administrative interface 
     134* [Contextual help menus](http://codex.wordpress.org/Administration_Panels#Help) display helpful information alongside settings choices 
     135* High-DPI icon support for administration menu 
    56136 
    57137= 1.0.2 = 
     
    95175* Added functionality to disable publishing to a page if access token fails. 
    96176* Clearer error messages for certain scenarios (like inability to post to a friend of page's Timeline because of privacy settings. 
    97 * Fixed conflicts with Power Editor and extraneous text being added to og:description.  Thanks to Angelo Mandato (http://wordpress.org/support/topic/plugin-facebook-plugin-conflicts-with-powerpress?replies=16) 
     177* Fixed conflicts with Power Editor and extraneous text being added to og:description.  Thanks to Angelo Mandato ([support mention](http://wordpress.org/support/topic/plugin-facebook-plugin-conflicts-with-powerpress)) 
    98178 
    99179= 1.0 = 
Note: See TracChangeset for help on using the changeset viewer.