web-dev-qa-db-ja.com

条件付きでFacebookを読み込む PHP ショートコードのSDK

3.3以降、ショートコード関数に条件付きでスクリプトをエンキューできますが、PHPクラス(session_start()関数で__construct()を使用)でこれを実行しようとすると、headers already sentエラーが発生します。

問題は、(これは Facebook PHP SDKをJS SDK と組み合わせて使用​​している)ということです。ショートコードが投稿に存在し、現在の投稿に2つのメタフィールドがすでに入力されている場合はインスタンス化されます(クラスにはこれら2つの値[App IDとApp Secret]が必要です)。

これに対する簡単な解決策はありますか?もしそうなら、私はこれを可能にするために次のコードで何を変更できますか?

public function fb_connect_shortcode( $atts, $content = null ) {
    extract( shortcode_atts( array( ), $atts ) ); /**/ global $post;
    $app_id = get_post_meta( $post->ID, $this->meta_prefix . 'AppID', true );
    $app_secret = get_post_meta( $post->ID, $this->meta_prefix . 'AppSecret', true );

    if( $app_id !== '' && $app_secret !== '' ) {

        /**
         * This is the class I am trying to instantiate conditionally
         * but since it uses session_start(), it can't send out headers
         */
        $facebook = new Facebook( array(
          'appId'  => $app_id,
          'secret' => $app_secret,
        ) );

        // See if there is a user from a cookie
        $user = $facebook->getUser();

        if( $user ) {
            try {
                // Proceed knowing you have a logged in user who's authenticated.
                $user_profile = $facebook->api( '/me' );
                $app_id = $facebook->getAppId();
            } catch( FacebookApiException $e ) {
                echo '<pre>' . htmlspecialchars( print_r( $e, true ) ) . '</pre>';
                $user = null;
            }
        }

        wp_enqueue_script( 'jw-fbsdk', plugins_url( 'jw-fbsdk.js', __FILE__ ), array(), '3.3.1', true );
        wp_localize_script( 'jw-fbsdk', 'jwuc', array(
            'appId' => $app_id,
            'channelUrl' => plugins_url( 'channel.php', __FILE__ )
        ) );

        if( is_null( $content ) )
            $content = 'Connect with Facebook';

        if( isset( $user_profile ) && $user_profile ) {
            return $user_profile['name'];
        } else {
            return '<div class="fb-login-button" data-scope="email,publish_stream,read_stream,status_update">' . $content . '</div>';
        }

    } else {

        return "You forgot to add your App ID and/or App Secret! Facebook needs these. :)";

    }

}
2
Jared

私はこれを自分で解決しましたが、@Bainternetの助けを借りて(投稿コンテンツにショートコードがあるかどうかチェックします)。

私がしたのは、クラス内にfacebookという名前の変数を作成し、そこにPHP SDKクラスを格納したことです。いくつか設定して正しければ、wpフックを使用してFacebookクラスを開始しました。このフックを使用すると、global $postを使用してメタ値を取得できます。

require 'facebook.php';
$urgent = JW_Urgent::getInstance();

class JW_Urgent {

    private static $instance;
    public $facebook;

    // Construct the class' data
    private function __construct() {

        $this->facebook = null;

        add_action( 'wp', array( &$this, 'define_facebook' ) );
        add_shortcode( 'jw-connect', array( &$this, 'fb_connect_shortcode' ) );

    }

    public static function getInstance() {
        if ( is_null( self::$instance ) )
            self::$instance = new JW_Urgent();

        return self::$instance;
    }


    public function define_facebook() {
        global $post;

        $app_id = get_post_meta( $post->ID, $this->meta_prefix . 'AppID', true );
        $app_secret = get_post_meta( $post->ID, $this->meta_prefix . 'AppSecret', true );

        if( !is_null( $post ) && ( $app_id !== '' && $app_secret !== '' ) && $post->post_type == $this->post_type ) {

            if( strpos( $post->post_content, '[jw-connect' ) !== false ) {

                $this->facebook = new Facebook( array(
                    'appId' => $app_id,
                    'secret' => $app_secret
                ) );

            }

        }

    }

    public function fb_connect_shortcode( $atts, $content = null ) {
        extract( shortcode_atts( array( ), $atts ) ); /**/ global $post;
        $app_id = get_post_meta( $post->ID, $this->meta_prefix . 'AppID', true );
        $app_secret = get_post_meta( $post->ID, $this->meta_prefix . 'AppSecret', true );

        if( $app_id !== '' && $app_secret !== '' && !is_null( $this->facebook ) ) {

            // See if there is a user from a cookie
            $user = $this->facebook->getUser();

            if( $user ) {
                try {
                    // Proceed knowing you have a logged in user who's authenticated.
                    $user_profile = $this->facebook->api( '/me' );
                    $app_id = $this->facebook->getAppId();
                } catch( FacebookApiException $e ) {
                    echo '<pre>' . htmlspecialchars( print_r( $e, true ) ) . '</pre>';
                    $user = null;
                }
            }

            wp_enqueue_script( 'jw-fbsdk', plugins_url( 'jw-fbsdk.js', __FILE__ ), array(), '3.3.1', true );
            wp_localize_script( 'jw-fbsdk', 'jwuc', array(
                'appId' => $app_id,
                'channelUrl' => plugins_url( 'channel.php', __FILE__ )
            ) );

            if( is_null( $content ) )
                $content = 'Connect with Facebook';

            if( isset( $user_profile ) && $user_profile ) {
                return $user_profile['name'];
            } else {
                return '<div class="fb-login-button" data-scope="email,publish_stream,read_stream,status_update">' . $content . '</div>';
            }

        } else {

            return "You forgot to add your App ID and/or App Secret! Facebook needs these. :)";

        }

    }

}
0
Jared

the_postsフィルタを使ってあなたのショートコードを検索してsdkを要求することができます。

function has_my_FB_shortcode($posts) {
    if ( empty($posts) )
        return $posts;
    $found = false;
    foreach ($posts as $post) {
        if ( stripos($post->post_content, '[my_shortcode') ){
            $found = true;
            break;
        }
    }

    if ($found)
        require('path/to/facebook_sdk.php');

    return $posts;
}
add_action('the_posts', 'has_my_FB_shortcode');
1
Bainternet