2

I would like some advice on how to improve the code I use for allowing people to comment posts.

Users can only submit a comment if they are connected with Facebook. I started developping this feature directly in the comments.php template. It works but there is another feature which permit people to publish a message on their wall if they tick a checkbox before sending the comment.

I have some troubles for developping this functionnality because I need an instance of the Facebook class. I already have it in my comments.php and I was wondering if there was a way to use it instead of creating a new one. Here is the code :

comments.php:

<?php 
locate_template( 'include/facebook.php', true );

$config = array();
$config['appId'] = get_option( 'appId' );
$config['secret'] = get_option( 'secret' );

$facebook = new Facebook($config);
$session = $facebook->getUser();
if(!$session){
    $loginUrl = $facebook->getLoginUrl(array('scope'=>'publish_stream, email', 'redirect_uri'=>'http://www.myredirecturi.fr'));
}

if( !isset( $session ) || empty( $session ) ){    
    ?>
    <div class="btns">
        <div class="fb-connect">
            <a href="<?php echo $loginUrl; ?>"><img src="<?php echo get_template_directory_uri(); ?>/img/btn-fb.png" alt=""></a>
        </div>
    </div>
    <?php
}

$nb_coms = get_comments_number();
if( $nb_coms != 0 ){
    wp_list_comments('callback=custom_comment&avatar_size=50');
}
?>

<?php
if($session){    
    try {    
        $me = $facebook->api('/me');
        $username = $me['username'];
        $firstname = $me['first_name'];
        $email = $me['email'];

        // I display here my custom comment form        
    }    
    catch(FacebookApiException $e){    
        error_log($e);    
    }
}
?>

functions.php

<?php
add_action( 'comment_post', 'custom_save_comment_data' );  
function custom_save_comment_data( $comment_id ) {  

    add_comment_meta( $comment_id, 'fb_username', $_POST['fb_username'] );

    //if( isset($_POST['publish']) ){
    //  $params = array(
    //                  'message'       =>  "Hurray! This works :)",
    //                  'name'          =>  "This is my title",
    //                  'caption'       =>  "My Caption",
    //                  'description'   =>  "Some Description...",
    //                  'link'          =>  "http://stackoverflow.com",
    //                  'picture'       =>  "http://i.imgur.com/VUBz8.png",
    //              );
    //  $user = $_POST['fb_userid'];
    //    $post = $facebook->api("/$user/feed","POST",$params);
    //}
}
?>

What do you recommend for pass the facebook object ? Does the way I developped these features is correct ? or should I create a plugin ? if it's the case, why ?

0

or should I create a plugin ? if it's the case, why ?

Yes you should: Separation of concerns. A theme is the view of the application. As the facebook functionality is part of your application, it belongs into a plugin.

You have one large benefit from moving stuff into plugins: If you exchange your theme, you can easily switch themes without loosing the functionality and having to code all that again.

And always use hooks and (even better) filters to bring stuff into templates. Hooks like the_content, start_loop, end_loop and the_post are perfect for attaching plugin output to the view. And they're present per default as core injects them into loops.

  • Thank you for your clear answer. I'll try to developpe a plugin. Do you have any idea for passing the object ? – aguidis Sep 9 '13 at 13:34
  • @AdrienG Filter or hook, as stated. Take a look at the Plugin API in Codex. – kaiser Sep 9 '13 at 15:25
  • 1
    Just finished my plugin... it's clean now, thanks again :) – aguidis Sep 9 '13 at 15:53
  • @AdrienG You're welcome. Mind to show/share your implementation details to later visitors in a separate answer? Might get some upvotes, more reputation points and therefore privileges :) – kaiser Sep 9 '13 at 15:56
  • 1
    Ok I'll share the code in a separate answer but I have to clean the plugin before :) (there is a lot of HTML) – aguidis Sep 9 '13 at 16:06
1

When I developped this little plugin, I used a part of the code of Danny van Kooten's plugin : 'Recent Facebook Posts'. The content of the plugin folder is :

classes /
    facebook-php-sdk/
        base_facebook.php
        facebook.php
        fb_ca_chain_bundle.crt
    class-fcwpc.php
fbconnect_wordpress_comments.php

fbconnect_wordpress_comments.php:

<?php
/*
Plugin Name: FB Connect WP Comments
Description: Allow people to comment if they are Facebook connected.
Version: 1.0
*/

require_once dirname(__FILE__) . '/classes/class-fcwpc.php';

$FBWPC = FBWPC::get_instance();
?>

class-fcwpc.php:

<?php

class FBWPC {

    private static $instance;
    private static $fb_instance;
    private $options;

    public static function get_instance() {
        if(!self::$instance) self::$instance = new FBWPC();
        return self::$instance;
    }

    public function __construct() {

        add_action('init', array($this, 'on_init'));

        add_action( 'comment_post', array($this, 'save_comment_data') ); 

        add_shortcode('fbconnect-wp-comments', array($this, 'shortcode_output'));
    }

    public function on_init() {
        if(!session_id() && !headers_sent()) {
            session_start();
        }
    }

    public function get_options() {
        if(!$this->options) {

            $defaults = array(
                'app_id' => get_option( 'appId' ),
                'app_secret' => get_option( 'secret' )
                );

            $this->options = $defaults;
        }
        return $this->options;
    }

    public function getFBApi() {
        if(!self::$fb_instance) {

            // Only load Facebook class if it has not been loaded yet
            // Other plugins may have loaded the class already at this point.
            if(!class_exists("Facebook")) {
                require_once dirname(__FILE__) . '/facebook-php-sdk/facebook.php';
            }

            $opts = $this->get_options();

            self::$fb_instance = new Facebook(array(
                'appId' => trim($opts['app_id']),
                'secret' => trim($opts['app_secret']),
                ));
        }

        return self::$fb_instance;
    }

    public function get_session() {

        $fb = $this->getFBApi();

        $session = $fb->getUser();
        return $session;
    }

    public function save_comment_data( $comment_id ) {  
        $fb = $this->getFBApi();
        // I need this data to display the profil picture thanks to the url : http://graph.facebook.com/'. $fb_username .'/picture
        add_comment_meta( $comment_id, 'fb_username', $_POST['fb_username'] );

        // test message
        if( isset($_POST['publish']) ){
            $params = array(
                          'message'       =>  "Hurray! This works :)",
                          'name'          =>  "This is my title",
                          'caption'       =>  "My Caption",
                          'description'   =>  "Some Description...",
                          'link'          =>  "http://stackoverflow.com",
                          'picture'       =>  "http://i.imgur.com/VUBz8.png",
                      );
            $user = $_POST['fb_userid'];
            $post = $fb->api("/$user/feed","POST",$params);
        }
    }

    public function shortcode_output()
    {

        $session = $this->get_session();
        $fb = $this->getFBApi();
        if(!$session){
          $loginUrl = $fb->getLoginUrl(array('scope'=>'publish_stream, email', 'redirect_uri'=>'http://yourRedirectUri.com/'));
        }

        if( !isset( $session ) || empty( $session ) ){  
            $output = '<div class="btns">
                <div class="fb-connect">
                    <a href="'. $loginUrl. '"><img src="'. get_template_directory_uri(). '/img/btn-fb.png" alt=""></a>
                </div>
            </div>';
        }

        $output .= '<ul>';
        if( $nb_coms != 0 ){

            $comments = get_comments();
            foreach($comments as $comment) :
                $fb_username = get_comment_meta( $comment->comment_ID, 'fb_username', true );
                $output .=  '<li id="list-comment-'. $comment->comment_ID .'">
                <img src="http://graph.facebook.com/'. $fb_username .'/picture" alt="" height="100" width="100">
                <span class="name">'. $comment->comment_author .'</span>
                <p>'. $comment->comment_content .'</p>
                <div class="date">'. $comment->comment_date .'</div>
                </li>';
            endforeach;
        }
        $output .= '</ul>';

        if ( comments_open() ) :
            if($session){  
                try {  
                    $me = $fb->api('/me');
                    $username = $me['username'];
                    $firstname = $me['first_name'];
                    $email = $me['email'];

                    $output .= '<form action="'. get_site_url(). '/wp-comments-post.php" method="post">
                        <img src="http://graph.facebook.com/'. $username. '/picture" alt="" height="50" width="50">
                        <div class="fieldslist">
                            <input id="author" name="author" type="hidden" value="'. $firstname. '">
                            <input id="fb_username" name="fb_username" type="hidden" value="'. $username. '">
                            <input id="email" name="email" type="hidden" value="'. $email. '">
                            <input id="fb_userid" name="fb_userid" type="hidden" value="'. $session. '">
                            <textarea name="comment" cols="45" rows="8" aria-required="true"></textarea>
                            <div class="submit">
                                <input type="checkbox" name="publish">
                                <label>Publish on your wall</label>
                                <input type="hidden" name="comment_post_ID" value="'. get_the_ID(). '" id="comment_post_ID">
                                <input type="submit" value="Comment">
                            </div>
                        </div>
                    </form>';
                }  
                catch(FacebookApiException $e){  
                    error_log($e);  
                }
            }
        endif;
        return $output;
    }
}

The file comments.php in your theme

<div class="coms">
    <?php echo do_shortcode('[fbconnect-wp-comments]');  ?>
</div>

I cleaned very quickly the code so I don't know if it will look great when you will test.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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