Facebook.php 6.83 KB
<?php
/**
 * Note: If there is an inconsistent error
 * it's due to how I changed the FB load
 * process, may need to change how JS is loaded
 * Proabably move FB.init and FB.Event.subscribe
 * to my init method
 * 
 * This needs to go in the <html tag
 * xmlns:fb="http://www.facebook.com/2008/fbml"
 *
 * http://wpdev.tenzinghost.com
 * API Key:    83f54e078b9aa0e303bba959dc0a566f
 * App Secret: e542aca35ab698121fa5917211013a41
 * App ID:     105917066126941
 * 
 * http://wp.cb
 * API Key:    3bcccfd8c28c52197141266d9e417649
 * App Secret: 9bfcd828bc6ccef12336dea57df93ecb
 * App ID:     138943536118944
 *
 * Graph API Reference:
 * http://developers.facebook.com/docs/reference/api/user
 */

namespace Tz\WordPress\Tools\Auth\Facebook;

use Tz\WordPress\Tools;
use Tz\WordPress\Tools\Auth;

use FB;

use Exception;

use InvalidArgumentException;

const OPTION_NAME = 'tz_auth_fb';

//setcookie('wpfb_logout', '', time() - 3600, '/');

    call_user_func(function() {
        Vars::$options = new Tools\WP_Option(OPTION_NAME, Array('button_title' => 'Login'));

        Tools\add_actions(__NAMESPACE__ . '\Actions');
        Tools\add_shortcodes(__NAMESPACE__ . '\ShortCodes');

        if (is_admin()) {
            require_once(__DIR__ . DIRECTORY_SEPARATOR . 'Settings.php');
        }
    });

/**
 * Generates markup for a Facebook Login button
 * @param {Boolean} $echo TRUE to echo the button, false to return a string
 * @returns NULL|String
 */
function drawLoginButton($echo = true) {
    $title = Vars::$options['button_title'] ?: 'Login';
    $btn = '<a id="TzFB" class="fb_button fb_button_medium"><span class="fb_button_text">' . $title . '</span></a>';
    $btn = '<fb:login-button></fb:login-button>';

    if (!$echo) {
        return $btn;
    }

    echo $btn;
}

// This might need some work...what happens if the object fails?
function getSDK() {
    static $instance = false;
    if (false === $instance) {
        require_once(__DIR__ . DIRECTORY_SEPARATOR . 'facebook-sdk.php');
        $instance = new FB\Facebook(Array(
            'appId'  => Vars::$options['application_id']
          , 'secret' => Vars::$options['application_secret']
          , 'cookie' => true
          , 'domain' => Vars::$options['domain_name']
        ));
    }

    return $instance;
}

function load() {
?>
<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    FB.init({appId: '<?php echo Vars::$options['application_id']; ?>', status: true, cookie: true, xfbml: true});

    FB.getLoginStatus(function(response) {
        console.log(response.status);
    });

    FB.Event.subscribe('auth.login', function(response) { window.location.reload(); });

<?php if (isset($_COOKIE['wpfb_logout'])): ?>
    FB.getLoginStatus(function(response) {
        if (response.session) {
            FB.logout(function() {
                var date = new Date();
                date.setTime(date.getTime() - 1);
                document.cookie = 'wpfb_logout=;expires=' + date.toGMTString() + ';path=/';
                
//                window.location.reload();
            });
        }
    });
<?php endif; ?>
  };

  (function() {
    var e   = document.createElement('script');
    e.async = true;
    e.src   = document.location.protocol + '//connect.facebook.net/en_US/all.js';
    document.getElementById('fb-root').appendChild(e);
  }());
</script>
<?php
}

/*
 * Logic for all these methods needs to be re-thought out
 * Should only load FB stuff when something happens (decide)
 * 1) drawLoginButton() has been called
 * 2) User is on the login_page
 * 3) Some other clever way of deciding if FB stuff should load
 */
class Actions {
    /**
     * Logs the user in to WP if they logged into FB
     * @global $post
     */
    public static function set_current_user() {
        $sdk = getSDK();
        if (null === ($sess = $sdk->getSession())) {
            return;
        }

        if (isset($_COOKIE['wpfb_logout'])) {
            $sdk->setSession();
            return;
        }

        // if user is not logged in do the following
        // if user is logged in merge account? do checks?

        // User is not logged into WP and has just logged in via FB

        // need try/catch here - I think I got an OAuthException at one point

        try {
            $info = $sdk->api('/me');
            $username = 'fbc' . $sess['uid'];
        } catch (FB\FacebookApiException $e) {
            return;
        }

        require_once(ABSPATH . WPINC . DIRECTORY_SEPARATOR . 'registration.php');
        if (username_exists($username)) {
            $user = Auth\signin($username);
        } else {
            if (false !== get_user_by('email', $info['email'])) {
                // Not sure if I can throw exception, this is outside the theme stuff...
                throw new Exception('email conflict');
            }

            try {
                $key  = Auth\register($username, $info['email'], _generate_password());
                $id   = Auth\activate($key);
                $user = Auth\signin($username);
            } catch (Exception $e) {
                // many types of exceptions
            }
        }

        foreach (Vars::$options['ext_perms'] as $key => $on) {
// I need to map some keys to WordPress presets
//            update_user_meta($user->ID, $key, $info[$key]);
        }
    }

    /**
     * Load the Facebook scripts for login
     */
    public static function OFF_wp_enqueue_scripts() {
        _enqueue_script('facebook-all', 'http://connect.facebook.net/en_US/all.js');
        _enqueue_script('tz-facebook', Tools\url('tz-facebook.js', __FILE__), Array('addEvent', 'Cookie'));

        _localize_script('tz-facebook', 'TzFBData', Array('AppID' => Vars::$options['application_id'], 'ext_perms' => implode(',', array_keys(Vars::$options['ext_perms'])), 'loginPage' => get_permalink(Auth\Vars::$options['login_page'])));
    }

    /**
     * Creates the anchor needed for Facebook scripts
     */
    public static function OFF_get_footer() {
        echo '<div id="fb-root"></div>';
    }

    /**
     * Destroy Facebook session data on site if the log out of WordPress
     */
    public static function wp_logout() {
        setcookie('wpfb_logout', 1, 0, '/', Vars::$options['domain_name']);
    }
}

class ShortCodes {
    public static function fb_login_button() {
/*
        if (is_user_logged_in()) {
            return '';
        }
*/

        $sdk = getSDK();
        if ($sdk->getSession()) {
            ob_start();
            print_r($sdk->getSession());
            print_r($_COOKIE);
try {
            print_r($sdk->api('/me'));
} catch (Exception $e) {
    die('fuck');
}
            $data = '<pre>' . ob_get_contents() . '</pre>';
            ob_end_clean();

            return $data;
        } else {
            return drawLoginButton(false);
        }
    }
}

class Vars {
    /**
     * WordPress option for this module
     * @type WP_Option
     */
    public static $options;
}
?>