. * * @category Pugin * @package StatusNet * @author Zach Copley * @copyright 2010 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ if (!defined('STATUSNET')) { exit(1); } /** * Main class for Facebook single-sign-on plugin * * * Simple plugins can be implemented as a single module. Others are more complex * and require additional modules; these should use their own directory, like * 'local/plugins/{$name}/'. All files related to the plugin, including images, * JavaScript, CSS, external libraries or PHP modules should go in the plugin * directory. * * @category Plugin * @package StatusNet * @author Zach Copley * @copyright 2010 StatusNet, Inc. * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html AGPL 3.0 * @link http://status.net/ */ class FacebookSSOPlugin extends Plugin { public $appId = null; // Facebook application ID public $secret = null; // Facebook application secret public $facebook = null; // Facebook application instance public $dir = null; // Facebook SSO plugin dir /** * Initializer for this plugin * * Plugins overload this method to do any initialization they need, * like connecting to remote servers or creating paths or so on. * * @return boolean hook value; true means continue processing, false means stop. */ function initialize() { common_debug("XXXXXXXXXXXX " . $this->appId); // Check defaults and configuration for application ID and secret if (empty($this->appId)) { $this->appId = common_config('facebook', 'appid'); } if (empty($this->secret)) { $this->secret = common_config('facebook', 'secret'); } if (empty($this->facebook)) { common_debug('instantiating facebook obj'); $this->facebook = new Facebook( array( 'appId' => $this->appId, 'secret' => $this->secret, 'cookie' => true ) ); } common_debug("FACEBOOK = " . var_export($this->facebook, true)); return true; } /** * Cleanup for this plugin * * Plugins overload this method to do any cleanup they need, * like disconnecting from remote servers or deleting temp files or so on. * * @return boolean hook value; true means continue processing, false means stop. */ function cleanup() { return true; } /** * Load related modules when needed * * Most non-trivial plugins will require extra modules to do their work. Typically * these include data classes, action classes, widget classes, or external libraries. * * This method receives a class name and loads the PHP file related to that class. By * tradition, action classes typically have files named for the action, all lower-case. * Data classes are in files with the data class name, initial letter capitalized. * * Note that this method will be called for *all* overloaded classes, not just ones * in this plugin! So, make sure to return true by default to let other plugins, and * the core code, get a chance. * * @param string $cls Name of the class to be loaded * * @return boolean hook value; true means continue processing, false means stop. */ function onAutoload($cls) { $dir = dirname(__FILE__); //common_debug("class = " . $cls); switch ($cls) { case 'Facebook': include_once $dir . '/extlib/facebook.php'; return false; case 'FacebookloginAction': case 'FacebookadminpanelAction': include_once $dir . '/' . strtolower(mb_substr($cls, 0, -6)) . '.php'; return false; default: return true; } } /** * Map URLs to actions * * This event handler lets the plugin map URLs on the site to actions (and * thus an action handler class). Note that the action handler class for an * action will be named 'FoobarAction', where action = 'foobar'. The class * must be loaded in the onAutoload() method. * * @param Net_URL_Mapper $m path-to-action mapper * * @return boolean hook value; true means continue processing, false means stop. */ function onRouterInitialized($m) { // Always add the admin panel route $m->connect('admin/facebook', array('action' => 'facebookadminpanel')); // Only add these routes if an application has been setup on // Facebook for the plugin to use. if ($this->hasApplication()) { $m->connect('main/facebooklogin', array('action' => 'facebooklogin')); } return true; } /* * Add a login tab for Facebook, but only if there's a Facebook * application defined for the plugin to use. * * @param Action &action the current action * * @return void */ function onEndLoginGroupNav(&$action) { $action_name = $action->trimmed('action'); if ($this->hasApplication()) { $action->menuItem( common_local_url('facebooklogin'), _m('MENU', 'Facebook'), // TRANS: Tooltip for menu item "Facebook". _m('Login or register using Facebook'), 'facebooklogin' === $action_name ); } return true; } /** * Add a Facebook tab to the admin panels * * @param Widget $nav Admin panel nav * * @return boolean hook value */ function onEndAdminPanelNav($nav) { if (AdminPanelAction::canAdmin('facebook')) { $action_name = $nav->action->trimmed('action'); $nav->out->menuItem( common_local_url('facebookadminpanel'), // TRANS: Menu item. _m('MENU','Facebook'), // TRANS: Tooltip for menu item "Facebook". _m('Facebook integration configuration'), $action_name == 'facebookadminpanel', 'nav_facebook_admin_panel' ); } return true; } /* * Is there a Facebook application for the plugin to use? */ function hasApplication() { if (!empty($this->appId) && !empty($this->secret)) { return true; } else { return false; } } function onStartShowHeader($action) { // output
as close to as possible $action->element('div', array('id' => 'fb-root')); $session = $this->facebook->getSession(); $dir = dirname(__FILE__); // XXX: minify this $script = <<inlineScript( sprintf($script, json_encode($this->appId), json_encode($this->session) ) ); return true; } function onStartHtmlElement($action, $attrs) { $attrs = array_merge($attrs, array('xmlns:fb' => 'http://www.facebook.com/2008/fbml')); return true; } function onPluginVersion(&$versions) { $versions[] = array('name' => 'Facebook Single-Sign-On', 'version' => STATUSNET_VERSION, 'author' => 'Zach Copley', 'homepage' => 'http://status.net/wiki/Plugin:FacebookSSO', 'rawdescription' => _m('A plugin for single-sign-on with Facebook.')); return true; } }