Conditionally loading Facebook PHP SDK in shortcode

Since 3.3 we can enqueue scripts conditionally right in our shortcode functions, but when I tried to do this with some PHP class (uses session_start() in the __construct() function) as you can guess it gives me the headers already sent error.

The problem is (this is using the Facebook PHP SDK in conjunction with the JS SDK), I only want this class to be instantiated if a shortcode is present on the post and if the current post has 2 meta fields filled out already (the class needs these 2 values [App ID and App Secret]).

Read More

Is there a simple solution to this? If so, what can I change in the following code to allow this?

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. :)";

    }

}

Related posts

Leave a Reply

2 comments

  1. You can try to use the_posts filter to search for you shortcode and require the sdk, something like this:

    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');
    
  2. I ended up solving this myself, but with help from @Bainternet (checking if shortcode is present in the post content).

    What I did was created a variable in my class called facebook, where I store the PHP SDK class. I used the wp hook to start the Facebook class if a few things are set and correct, this hook is allowing me to use global $post so that I can grab the meta values.

    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. :)";
    
            }
    
        }
    
    }