2

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]).

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

    }

}

2 Answers 2

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');
1
  • Thanks, it seems to be almost working fine now. Is there a way to get the current queried post in this function? That would be the last little thing I need. I checked the $wp_query global but didn't hold any identifying post ID for the current post, but all of them.
    – Jared
    Commented Feb 27, 2012 at 20:15
0

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

        }

    }

}
1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.