Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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

    }

}
share|improve this question
add comment

2 Answers 2

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');
share|improve this answer
    
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 Feb 27 '12 at 20:15
add comment
up vote 0 down vote accepted

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

        }

    }

}
share|improve this answer
    
Do you mind helping this user out stackoverflow.com/questions/10825763/… –  phwd May 31 '12 at 15:51
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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