web-dev-qa-db-fra.com

Chargement conditionnel de Facebook PHP SDK en shortcode

Depuis la version 3.3, nous pouvons mettre en file d'attente les scripts de manière conditionnelle dans nos fonctions de shortcode, mais lorsque j'ai essayé de le faire avec une classe PHP (utilise session_start() dans la fonction __construct()), vous pouvez deviner que l'erreur headers already sent apparaît.

Le problème est (ceci utilise le SDK Facebook PHP en conjonction avec le SDK JS ), je veux seulement que cette classe soit instanciée si un shortcode est présent sur le post et si le post actuel a déjà 2 champs méta remplis (la classe a besoin de ces 2 valeurs [App ID et App Secret]).

Y a-t-il une solution simple à cela? Si oui, que puis-je changer dans le code suivant pour permettre cela?

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

J'ai fini par résoudre ce problème moi-même, mais avec l'aide de @Bainternet (en vérifiant si un shortcode est présent dans le contenu du message).

Ce que j'ai fait a été créé une variable dans ma classe appelée facebook, où je stocke la classe PHP SDK. J'ai utilisé le hook wp pour démarrer la classe Facebook si quelques éléments sont définis et corrects. Ce hook me permet d'utiliser global $post afin de pouvoir récupérer les méta-valeurs.

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

Vous pouvez essayer d'utiliser le filtre the_posts pour rechercher votre shortcode et exiger le sdk, quelque chose comme ceci:

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