From 4ac7a4054e31241813404cdfdf2cb5e8cf97b4f1 Mon Sep 17 00:00:00 2001 From: Evan Prodromou Date: Fri, 15 May 2009 13:55:49 -0400 Subject: [PATCH 1/4] conversation tree interface --- actions/conversation.php | 96 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 2 deletions(-) diff --git a/actions/conversation.php b/actions/conversation.php index 05cfb76e3c..f3beade6c7 100644 --- a/actions/conversation.php +++ b/actions/conversation.php @@ -42,6 +42,7 @@ require_once(INSTALLDIR.'/lib/noticelist.php'); * @license http://www.fsf.org/licensing/licenses/agpl.html AGPLv3 * @link http://laconi.ca/ */ + class ConversationAction extends Action { var $id = null; @@ -95,9 +96,9 @@ class ConversationAction extends Action 'notice:conversation:'.$this->id, $offset, $limit); - $nl = new NoticeList($notices, $this); + $ct = new ConversationTree($notices, $this); - $cnt = $nl->show(); + $cnt = $ct->show(); $this->pagination($this->page > 1, $cnt > NOTICES_PER_PAGE, $this->page, 'conversation', array('id' => $this->id)); @@ -105,3 +106,94 @@ class ConversationAction extends Action } +class ConversationTree extends NoticeList +{ + var $tree = null; + var $table = null; + + function show() + { + $cnt = 0; + + $this->tree = array(); + $table = array(); + + while ($this->notice->fetch()) { + $cnt++; + $this->table[$this->notice->id] = clone($this->notice); + if (is_null($notice->reply_to)) { + // We assume no notice has -1 ID + $this->tree[-1] = array($notice->id); + } else if (array_key_exists($notice->reply_to, $this->tree)) { + $this->tree[$notice->reply_to][] = $notice->id; + } else { + $this->tree[$notice->reply_to] = array($notice->id); + } + } + + $this->out->elementStart('div', array('id' =>'notices_primary')); + $this->out->element('h2', null, _('Notices')); + $this->out->elementStart('ul', array('class' => 'notices')); + + if (array_key_exists(-1, $this->tree)) { + $this->showNoticePlus($this->tree[-1][0]); + } + + $this->out->elementEnd('ul'); + $this->out->elementEnd('div'); + + return $cnt; + } + + function showNoticePlus($id) + { + $notice = $this->table[$id]; + + print_r($notice); + + // We take responsibility for doing the li + + $this->out->elementStart('li', array('class' => 'hentry notice', + 'id' => 'notice-' . $this->notice->id)); + + $item = $this->newListItem($notice); + $item->show(); + + if (array_key_exists($id, $this->tree)) { + $children = $this->tree[$id]; + + $this->out->elementStart('ul', array('class' => 'notices')); + + foreach ($children as $child) { + $this->showNoticePlus($child); + } + + $this->out->elementEnd('ul'); + } + + $this->out->elementEnd('li'); + } + + function newListItem($notice) + { + return new ConversationTreeItem($notice, $this->out); + } +} + +class ConversationTreeItem extends NoticeListItem +{ + function showStart() + { + // skip; ConversationTree draws the list + } + + function showEnd() + { + // skip; ConversationTree draws the list + } + + function showContext() + { + // skip; this _is_ the context! + } +} \ No newline at end of file From 8545a1c5fe65e056b4dd7fca5464cc927a43b38a Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Wed, 20 May 2009 06:46:11 +0000 Subject: [PATCH 2/4] Reorganized some stuff and made new Facebook Login tab --- plugins/FBConnect/FBCLoginGroupNav.php | 112 ++++++++ plugins/FBConnect/FBConnectAuth.php | 370 +++++++++++++++++++++++++ plugins/FBConnect/FBConnectLogin.php | 362 ++---------------------- plugins/FBConnect/FBConnectPlugin.php | 39 ++- 4 files changed, 546 insertions(+), 337 deletions(-) create mode 100644 plugins/FBConnect/FBCLoginGroupNav.php create mode 100644 plugins/FBConnect/FBConnectAuth.php diff --git a/plugins/FBConnect/FBCLoginGroupNav.php b/plugins/FBConnect/FBCLoginGroupNav.php new file mode 100644 index 0000000000..9aa01a0940 --- /dev/null +++ b/plugins/FBConnect/FBCLoginGroupNav.php @@ -0,0 +1,112 @@ +. + * + * @category Menu + * @package Laconica + * @author Evan Prodromou + * @author Zach Copley + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR . '/lib/widget.php'; + +/** + * Menu for login group of actions + * + * @category Output + * @package Laconica + * @author Evan Prodromou + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + * @see Widget + */ + +class FBCLoginGroupNav extends Widget +{ + var $action = null; + + /** + * Construction + * + * @param Action $action current action, used for output + */ + + function __construct($action=null) + { + parent::__construct($action); + $this->action = $action; + } + + /** + * Show the menu + * + * @return void + */ + + function show() + { + common_debug('FBCLoginGroupNav'); + + $this->action->elementStart('dl', array('id' => 'site_nav_local_views')); + $this->action->element('dt', null, _('Local views')); + $this->action->elementStart('dd'); + + // action => array('prompt', 'title') + $menu = array(); + + $menu['login'] = array(_('Login'), + _('Login with a username and password')); + + if (!(common_config('site','closed') || common_config('site','inviteonly'))) { + $menu['register'] = array(_('Register'), + _('Sign up for a new account')); + } + + $menu['openidlogin'] = array(_('OpenID'), + _('Login or register with OpenID')); + + $menu['FBConnectLogin'] = array(_('Facebook'), + _('Login or register using Facebook')); + + $action_name = $this->action->trimmed('action'); + $this->action->elementStart('ul', array('class' => 'nav')); + + foreach ($menu as $menuaction => $menudesc) { + $this->action->menuItem(common_local_url($menuaction), + $menudesc[0], + $menudesc[1], + $action_name === $menuaction); + } + + $this->action->elementEnd('ul'); + + $this->action->elementEnd('dd'); + $this->action->elementEnd('dl'); + } +} diff --git a/plugins/FBConnect/FBConnectAuth.php b/plugins/FBConnect/FBConnectAuth.php new file mode 100644 index 0000000000..0dc016c05c --- /dev/null +++ b/plugins/FBConnect/FBConnectAuth.php @@ -0,0 +1,370 @@ +. + * + * @category Plugin + * @package Laconica + * @author Zach Copley + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +require_once INSTALLDIR . '/plugins/FBConnect/FBConnectPlugin.php'; + +class FbconnectauthAction extends Action +{ + + var $fbuid = null; + var $fb_fields = null; + + function prepare($args) { + parent::prepare($args); + + $this->fbuid = getFacebook()->get_loggedin_user(); + $this->fb_fields = $this->getFacebookFields($this->fbuid, + array('first_name', 'last_name', 'name')); + + return true; + } + + function handle($args) + { + parent::handle($args); + + if (common_is_real_login()) { + $this->clientError(_('Already logged in.')); + } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $token = $this->trimmed('token'); + if (!$token || $token != common_session_token()) { + $this->showForm(_('There was a problem with your session token. Try again, please.')); + return; + } + if ($this->arg('create')) { + if (!$this->boolean('license')) { + $this->showForm(_('You can\'t register if you don\'t agree to the license.'), + $this->trimmed('newname')); + return; + } + $this->createNewUser(); + } else if ($this->arg('connect')) { + $this->connectUser(); + } else { + common_debug(print_r($this->args, true), __FILE__); + $this->showForm(_('Something weird happened.'), + $this->trimmed('newname')); + } + } else { + $this->tryLogin(); + } + } + + function showPageNotice() + { + if ($this->error) { + $this->element('div', array('class' => 'error'), $this->error); + } else { + $this->element('div', 'instructions', + sprintf(_('This is the first time you\'ve logged into %s so we must connect your Facebook to a local account. You can either create a new account, or connect with your existing account, if you have one.'), common_config('site', 'name'))); + } + } + + function title() + { + return _('Facebook Account Setup'); + } + + function showForm($error=null, $username=null) + { + $this->error = $error; + $this->username = $username; + + $this->showPage(); + } + + function showPage() + { + parent::showPage(); + } + + function showContent() + { + if (!empty($this->message_text)) { + $this->element('p', null, $this->message); + return; + } + + $this->elementStart('form', array('method' => 'post', + 'id' => 'account_connect', + 'action' => common_local_url('fbconnectlogin'))); + $this->hidden('token', common_session_token()); + $this->element('h2', null, + _('Create new account')); + $this->element('p', null, + _('Create a new user with this nickname.')); + $this->input('newname', _('New nickname'), + ($this->username) ? $this->username : '', + _('1-64 lowercase letters or numbers, no punctuation or spaces')); + $this->elementStart('p'); + $this->element('input', array('type' => 'checkbox', + 'id' => 'license', + 'name' => 'license', + 'value' => 'true')); + $this->text(_('My text and files are available under ')); + $this->element('a', array('href' => common_config('license', 'url')), + common_config('license', 'title')); + $this->text(_(' except this private data: password, email address, IM address, phone number.')); + $this->elementEnd('p'); + $this->submit('create', _('Create')); + $this->element('h2', null, + _('Connect existing account')); + $this->element('p', null, + _('If you already have an account, login with your username and password to connect it to your Facebook.')); + $this->input('nickname', _('Existing nickname')); + $this->password('password', _('Password')); + $this->submit('connect', _('Connect')); + $this->elementEnd('form'); + } + + function message($msg) + { + $this->message_text = $msg; + $this->showPage(); + } + + function createNewUser() + { + + if (common_config('site', 'closed')) { + $this->clientError(_('Registration not allowed.')); + return; + } + + $invite = null; + + if (common_config('site', 'inviteonly')) { + $code = $_SESSION['invitecode']; + if (empty($code)) { + $this->clientError(_('Registration not allowed.')); + return; + } + + $invite = Invitation::staticGet($code); + + if (empty($invite)) { + $this->clientError(_('Not a valid invitation code.')); + return; + } + } + + $nickname = $this->trimmed('newname'); + + if (!Validate::string($nickname, array('min_length' => 1, + 'max_length' => 64, + 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) { + $this->showForm(_('Nickname must have only lowercase letters and numbers and no spaces.')); + return; + } + + if (!User::allowed_nickname($nickname)) { + $this->showForm(_('Nickname not allowed.')); + return; + } + + if (User::staticGet('nickname', $nickname)) { + $this->showForm(_('Nickname already in use. Try another one.')); + return; + } + + $fullname = trim($this->fb_fields['firstname'] . + ' ' . $this->fb_fields['lastname']); + + $args = array('nickname' => $nickname, 'fullname' => $fullname); + + if (!empty($invite)) { + $args['code'] = $invite->code; + } + + $user = User::register($args); + + $result = $this->flinkUser($user->id, $this->fbuid); + + if (!$result) { + $this->serverError(_('Error connecting user to Facebook.')); + return; + } + + common_set_user($user); + common_real_login(true); + + common_debug("Registered new user $user->id from Facebook user $this->fbuid"); + + common_redirect(common_local_url('showstream', array('nickname' => $user->nickname)), + 303); + } + + function connectUser() + { + $nickname = $this->trimmed('nickname'); + $password = $this->trimmed('password'); + + if (!common_check_user($nickname, $password)) { + $this->showForm(_('Invalid username or password.')); + return; + } + + $user = User::staticGet('nickname', $nickname); + + if ($user) { + common_debug("Legit user to connect to Facebook: $nickname"); + } + + $result = $this->flinkUser($user->id, $this->fbuid); + + if (!$result) { + $this->serverError(_('Error connecting user to Facebook.')); + return; + } + + common_debug("Connected Facebook user $this->fbuid to local user $user->id"); + + common_set_user($user); + common_real_login(true); + + $this->goHome($user->nickname); + } + + function tryLogin() + { + common_debug("Trying Facebook Login..."); + + $flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_SERVICE); + + if ($flink) { + $user = $flink->getUser(); + + if ($user) { + + common_debug("Logged in Facebook user $flink->foreign_id as user $user->id ($user->nickname)"); + + common_set_user($user); + common_real_login(true); + $this->goHome($user->nickname); + } + + } else { + $this->showForm(null, $this->bestNewNickname()); + } + } + + function goHome($nickname) + { + $url = common_get_returnto(); + if ($url) { + // We don't have to return to it again + common_set_returnto(null); + } else { + $url = common_local_url('all', + array('nickname' => + $nickname)); + } + + common_redirect($url, 303); + } + + function flinkUser($user_id, $fbuid) + { + $flink = new Foreign_link(); + $flink->user_id = $user_id; + $flink->foreign_id = $fbuid; + $flink->service = FACEBOOK_SERVICE; + $flink->created = common_sql_now(); + + $flink_id = $flink->insert(); + + return $flink_id; + } + + function bestNewNickname() + { + if (!empty($this->fb_fields['name'])) { + $nickname = $this->nicknamize($this->fb_fields['name']); + if ($this->isNewNickname($nickname)) { + return $nickname; + } + } + + // Try the full name + + $fullname = trim($this->fb_fields['firstname'] . + ' ' . $this->fb_fields['lastname']); + + if (!empty($fullname)) { + $fullname = $this->nicknamize($fullname); + if ($this->isNewNickname($fullname)) { + return $fullname; + } + } + + return null; + } + + // Given a string, try to make it work as a nickname + + function nicknamize($str) + { + $str = preg_replace('/\W/', '', $str); + return strtolower($str); + } + + function isNewNickname($str) + { + if (!Validate::string($str, array('min_length' => 1, + 'max_length' => 64, + 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) { + return false; + } + if (!User::allowed_nickname($str)) { + return false; + } + if (User::staticGet('nickname', $str)) { + return false; + } + return true; + } + + // XXX: Consider moving this to lib/facebookutil.php + function getFacebookFields($fb_uid, $fields) { + try { + $infos = getFacebook()->api_client->users_getInfo($fb_uid, $fields); + + if (empty($infos)) { + return null; + } + return reset($infos); + + } catch (Exception $e) { + error_log("Failure in the api when requesting " . join(",", $fields) + ." on uid " . $fb_uid . " : ". $e->getMessage()); + return null; + } + } + +} diff --git a/plugins/FBConnect/FBConnectLogin.php b/plugins/FBConnect/FBConnectLogin.php index c2a2885717..70710eb709 100644 --- a/plugins/FBConnect/FBConnectLogin.php +++ b/plugins/FBConnect/FBConnectLogin.php @@ -1,12 +1,9 @@ . - * - * @category Plugin - * @package Laconica - * @author Zach Copley - * @copyright 2009 Control Yourself, Inc. - * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 - * @link http://laconi.ca/ */ -require_once INSTALLDIR . '/plugins/FBConnect/FBConnectLogin.php'; -require_once INSTALLDIR . '/lib/facebookutil.php'; +if (!defined('LACONICA')) { + exit(1); +} -class FBConnectloginAction extends Action +require_once INSTALLDIR . '/plugins/FBConnect/FBConnectPlugin.php'; + +class FBConnectLoginAction extends Action { - - var $fbuid = null; - var $fb_fields = null; - - function prepare($args) { - parent::prepare($args); - - $this->fbuid = getFacebook()->get_loggedin_user(); - $this->fb_fields = $this->getFacebookFields($this->fbuid, - array('first_name', 'last_name', 'name')); - - return true; - } - function handle($args) { parent::handle($args); if (common_is_real_login()) { $this->clientError(_('Already logged in.')); - } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { - $token = $this->trimmed('token'); - if (!$token || $token != common_session_token()) { - $this->showForm(_('There was a problem with your session token. Try again, please.')); - return; - } - if ($this->arg('create')) { - if (!$this->boolean('license')) { - $this->showForm(_('You can\'t register if you don\'t agree to the license.'), - $this->trimmed('newname')); - return; - } - $this->createNewUser(); - } else if ($this->arg('connect')) { - $this->connectUser(); - } else { - common_debug(print_r($this->args, true), __FILE__); - $this->showForm(_('Something weird happened.'), - $this->trimmed('newname')); - } - } else { - $this->tryLogin(); - } + } + + $this->showPage(); + } + + function getInstructions() + { + return _('Login with your Facebook Account'); } function showPageNotice() { - if ($this->error) { - $this->element('div', array('class' => 'error'), $this->error); - } else { - $this->element('div', 'instructions', - sprintf(_('This is the first time you\'ve logged into %s so we must connect your Facebook to a local account. You can either create a new account, or connect with your existing account, if you have one.'), common_config('site', 'name'))); - } + $instr = $this->getInstructions(); + $output = common_markup_to_html($instr); + $this->elementStart('div', 'instructions'); + $this->raw($output); + $this->elementEnd('div'); } function title() { - return _('Facebook Account Setup'); + return _('Facebook Login'); } - function showForm($error=null, $username=null) - { - $this->error = $error; - $this->username = $username; + function showContent() { - $this->showPage(); - } + $this->elementStart('fieldset'); + - function showPage() - { - parent::showPage(); - } + $this->element('fb:login-button', array('onlogin' => 'goto_login()', + 'length' => 'long')); - function showContent() - { - if (!empty($this->message_text)) { - $this->element('p', null, $this->message); - return; - } - - $this->elementStart('form', array('method' => 'post', - 'id' => 'account_connect', - 'action' => common_local_url('fbconnectlogin'))); - $this->hidden('token', common_session_token()); - $this->element('h2', null, - _('Create new account')); - $this->element('p', null, - _('Create a new user with this nickname.')); - $this->input('newname', _('New nickname'), - ($this->username) ? $this->username : '', - _('1-64 lowercase letters or numbers, no punctuation or spaces')); - $this->elementStart('p'); - $this->element('input', array('type' => 'checkbox', - 'id' => 'license', - 'name' => 'license', - 'value' => 'true')); - $this->text(_('My text and files are available under ')); - $this->element('a', array('href' => common_config('license', 'url')), - common_config('license', 'title')); - $this->text(_(' except this private data: password, email address, IM address, phone number.')); - $this->elementEnd('p'); - $this->submit('create', _('Create')); - $this->element('h2', null, - _('Connect existing account')); - $this->element('p', null, - _('If you already have an account, login with your username and password to connect it to your Facebook.')); - $this->input('nickname', _('Existing nickname')); - $this->password('password', _('Password')); - $this->submit('connect', _('Connect')); - $this->elementEnd('form'); - } - - function message($msg) - { - $this->message_text = $msg; - $this->showPage(); - } - - function createNewUser() - { - - if (common_config('site', 'closed')) { - $this->clientError(_('Registration not allowed.')); - return; - } - - $invite = null; - - if (common_config('site', 'inviteonly')) { - $code = $_SESSION['invitecode']; - if (empty($code)) { - $this->clientError(_('Registration not allowed.')); - return; - } - - $invite = Invitation::staticGet($code); - - if (empty($invite)) { - $this->clientError(_('Not a valid invitation code.')); - return; - } - } - - $nickname = $this->trimmed('newname'); - - if (!Validate::string($nickname, array('min_length' => 1, - 'max_length' => 64, - 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) { - $this->showForm(_('Nickname must have only lowercase letters and numbers and no spaces.')); - return; - } - - if (!User::allowed_nickname($nickname)) { - $this->showForm(_('Nickname not allowed.')); - return; - } - - if (User::staticGet('nickname', $nickname)) { - $this->showForm(_('Nickname already in use. Try another one.')); - return; - } - - $fullname = trim($this->fb_fields['firstname'] . - ' ' . $this->fb_fields['lastname']); - - $args = array('nickname' => $nickname, 'fullname' => $fullname); - - if (!empty($invite)) { - $args['code'] = $invite->code; - } - - $user = User::register($args); - - $result = $this->flinkUser($user->id, $this->fbuid); - - if (!$result) { - $this->serverError(_('Error connecting user to Facebook.')); - return; - } - - common_set_user($user); - common_real_login(true); - - common_debug("Registered new user $user->id from Facebook user $this->fbuid"); - - common_redirect(common_local_url('showstream', array('nickname' => $user->nickname)), - 303); - } - - function connectUser() - { - $nickname = $this->trimmed('nickname'); - $password = $this->trimmed('password'); - - if (!common_check_user($nickname, $password)) { - $this->showForm(_('Invalid username or password.')); - return; - } - - $user = User::staticGet('nickname', $nickname); - - if ($user) { - common_debug("Legit user to connect to Facebook: $nickname"); - } - - $result = $this->flinkUser($user->id, $this->fbuid); - - if (!$result) { - $this->serverError(_('Error connecting user to Facebook.')); - return; - } - - common_debug("Connected Facebook user $this->fbuid to local user $user->id"); - - common_set_user($user); - common_real_login(true); - - $this->goHome($user->nickname); - } - - function tryLogin() - { - common_debug("Trying Facebook Login..."); - - $flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_SERVICE); - - if ($flink) { - $user = $flink->getUser(); - - if ($user) { - - common_debug("Logged in Facebook user $flink->foreign_id as user $user->id ($user->nickname)"); - - common_set_user($user); - common_real_login(true); - $this->goHome($user->nickname); - } - - } else { - $this->showForm(null, $this->bestNewNickname()); - } - } - - function goHome($nickname) - { - $url = common_get_returnto(); - if ($url) { - // We don't have to return to it again - common_set_returnto(null); - } else { - $url = common_local_url('all', - array('nickname' => - $nickname)); - } - - common_redirect($url, 303); - } - - function flinkUser($user_id, $fbuid) - { - $flink = new Foreign_link(); - $flink->user_id = $user_id; - $flink->foreign_id = $fbuid; - $flink->service = FACEBOOK_SERVICE; - $flink->created = common_sql_now(); - - $flink_id = $flink->insert(); - - return $flink_id; - } - - function bestNewNickname() - { - if (!empty($this->fb_fields['name'])) { - $nickname = $this->nicknamize($this->fb_fields['name']); - if ($this->isNewNickname($nickname)) { - return $nickname; - } - } - - // Try the full name - - $fullname = trim($this->fb_fields['firstname'] . - ' ' . $this->fb_fields['lastname']); - - if (!empty($fullname)) { - $fullname = $this->nicknamize($fullname); - if ($this->isNewNickname($fullname)) { - return $fullname; - } - } - - return null; - } - - // Given a string, try to make it work as a nickname - - function nicknamize($str) - { - $str = preg_replace('/\W/', '', $str); - return strtolower($str); - } - - function isNewNickname($str) - { - if (!Validate::string($str, array('min_length' => 1, - 'max_length' => 64, - 'format' => VALIDATE_NUM . VALIDATE_ALPHA_LOWER))) { - return false; - } - if (!User::allowed_nickname($str)) { - return false; - } - if (User::staticGet('nickname', $str)) { - return false; - } - return true; - } - - // XXX: Consider moving this to lib/facebookutil.php - function getFacebookFields($fb_uid, $fields) { - try { - $infos = getFacebook()->api_client->users_getInfo($fb_uid, $fields); - - if (empty($infos)) { - return null; - } - return reset($infos); - - } catch (Exception $e) { - error_log("Failure in the api when requesting " . join(",", $fields) - ." on uid " . $fb_uid . " : ". $e->getMessage()); - return null; - } + $this->elementEnd('fieldset'); } } diff --git a/plugins/FBConnect/FBConnectPlugin.php b/plugins/FBConnect/FBConnectPlugin.php index 191cede765..079270510d 100644 --- a/plugins/FBConnect/FBConnectPlugin.php +++ b/plugins/FBConnect/FBConnectPlugin.php @@ -31,8 +31,10 @@ if (!defined('LACONICA')) { exit(1); } -require_once INSTALLDIR . '/plugins/FBConnect/FBConnectLogin.php'; require_once INSTALLDIR . '/lib/facebookutil.php'; +require_once INSTALLDIR . '/plugins/FBConnect/FBConnectAuth.php'; +require_once INSTALLDIR . '/plugins/FBConnect/FBConnectLogin.php'; +require_once INSTALLDIR . '/plugins/FBConnect/FBCLoginGroupNav.php'; /** * Plugin to enable Facebook Connect @@ -54,7 +56,11 @@ class FBConnectPlugin extends Plugin // Hook in new actions function onRouterInitialized(&$m) { - $m->connect('main/facebookconnect', array('action' => 'fbconnectlogin')); + + common_debug("onRouterIntialized()"); + + $m->connect('main/facebookconnect', array('action' => 'FBConnectAuth')); + $m->connect('main/facebooklogin', array('action' => 'FBConnectLogin')); } // Add in xmlns:fb @@ -67,8 +73,10 @@ class FBConnectPlugin extends Plugin $name = get_class($action); + common_debug("onStartShowHTML: action = $name"); + // Avoid a redirect loop - if (!in_array($name, array('FBConnectloginAction', 'ClientErrorAction'))) { + if (!in_array($name, array('FBConnectAuthAction', 'ClientErrorAction'))) { $this->checkFacebookUser($action); @@ -246,7 +254,7 @@ class FBConnectPlugin extends Plugin } else { common_debug("Facebook user is NOT logged in."); - common_redirect(common_local_url('fbconnectlogin'), 303); + common_redirect(common_local_url('FBConnectAuth'), 303); } } else { @@ -259,7 +267,28 @@ class FBConnectPlugin extends Plugin } } - + + function onStartShowLocalNavBlock($action) + { + $action_name = get_class($action); + + common_debug($action_name); + + $login_actions = array('LoginAction', 'RegisterAction', + 'OpenidloginAction', 'FacebookStart'); + + if (in_array($action_name, $login_actions)) { + + common_debug("LoginAction found!"); + + $nav = new FBCLoginGroupNav($action); + $nav->show(); + return false; + } + + return true; + + } } From 54cd0a2046c417fd072bb4cf79aeda163cf760af Mon Sep 17 00:00:00 2001 From: Zach Copley Date: Thu, 21 May 2009 05:43:11 +0000 Subject: [PATCH 3/4] - Reworked login / logout workflow - Added Facebook Connect tab to login nav - Show Facebook mini-avatar when logged in - Added Facebook Connect tab to connect settings nav - Option to disconnect from Facebook --- db/foreign_services.sql | 3 +- plugins/FBConnect/FBCSettingsNav.php | 113 +++++++++++++++ plugins/FBConnect/FBConnectAuth.php | 31 +++- plugins/FBConnect/FBConnectLogin.php | 10 +- plugins/FBConnect/FBConnectPlugin.php | 179 +++++++++-------------- plugins/FBConnect/FBConnectSettings.php | 184 ++++++++++++++++++++++++ 6 files changed, 393 insertions(+), 127 deletions(-) create mode 100644 plugins/FBConnect/FBCSettingsNav.php create mode 100644 plugins/FBConnect/FBConnectSettings.php diff --git a/db/foreign_services.sql b/db/foreign_services.sql index 557ede0246..79c04cee56 100644 --- a/db/foreign_services.sql +++ b/db/foreign_services.sql @@ -2,4 +2,5 @@ insert into foreign_service (id, name, description, created) values ('1','Twitter', 'Twitter Micro-blogging service', now()), - ('2','Facebook', 'Facebook', now()); + ('2','Facebook', 'Facebook', now()), + ('3','FacebookConnect', 'Facebook Connect', now()); diff --git a/plugins/FBConnect/FBCSettingsNav.php b/plugins/FBConnect/FBCSettingsNav.php new file mode 100644 index 0000000000..8b84118532 --- /dev/null +++ b/plugins/FBConnect/FBCSettingsNav.php @@ -0,0 +1,113 @@ +. + * + * @category Menu + * @package Laconica + * @author Evan Prodromou + * @author Zach Copley + * @copyright 2009 Control Yourself, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + */ + +if (!defined('LACONICA')) { + exit(1); +} + +require_once INSTALLDIR . '/lib/widget.php'; + +/** + * A widget for showing the connect group local nav menu + * + * @category Output + * @package Laconica + * @author Evan Prodromou + * @author Zach Copley + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link http://laconi.ca/ + * + * @see Widget + */ + +class FBCSettingsNav extends Widget +{ + var $action = null; + + /** + * Construction + * + * @param Action $action current action, used for output + */ + + function __construct($action=null) + { + parent::__construct($action); + $this->action = $action; + } + + /** + * Show the menu + * + * @return void + */ + + function show() + { + + $this->action->elementStart('dl', array('id' => 'site_nav_local_views')); + $this->action->element('dt', null, _('Local views')); + $this->action->elementStart('dd'); + + # action => array('prompt', 'title') + $menu = + array('imsettings' => + array(_('IM'), + _('Updates by instant messenger (IM)')), + 'smssettings' => + array(_('SMS'), + _('Updates by SMS')), + 'twittersettings' => + array(_('Twitter'), + _('Twitter integration options')), + 'FBConnectSettings' => + array(_('Facebook'), + _('Facebook Connect settings'))); + + $action_name = $this->action->trimmed('action'); + $this->action->elementStart('ul', array('class' => 'nav')); + + foreach ($menu as $menuaction => $menudesc) { + if ($menuaction == 'imsettings' && + !common_config('xmpp', 'enabled')) { + continue; + } + $this->action->menuItem(common_local_url($menuaction), + $menudesc[0], + $menudesc[1], + $action_name === $menuaction); + } + + $this->action->elementEnd('ul'); + + $this->action->elementEnd('dd'); + $this->action->elementEnd('dl'); + } +} diff --git a/plugins/FBConnect/FBConnectAuth.php b/plugins/FBConnect/FBConnectAuth.php index 0dc016c05c..e8724cdf9a 100644 --- a/plugins/FBConnect/FBConnectAuth.php +++ b/plugins/FBConnect/FBConnectAuth.php @@ -29,7 +29,7 @@ require_once INSTALLDIR . '/plugins/FBConnect/FBConnectPlugin.php'; -class FbconnectauthAction extends Action +class FBConnectauthAction extends Action { var $fbuid = null; @@ -38,9 +38,20 @@ class FbconnectauthAction extends Action function prepare($args) { parent::prepare($args); - $this->fbuid = getFacebook()->get_loggedin_user(); - $this->fb_fields = $this->getFacebookFields($this->fbuid, - array('first_name', 'last_name', 'name')); + try { + + $this->fbuid = getFacebook()->get_loggedin_user(); + + if ($this->fbuid > 0) { + $this->fb_fields = $this->getFacebookFields($this->fbuid, + array('first_name', 'last_name', 'name')); + } else { + common_debug("No Facebook User found."); + } + + } catch (Exception $e) { + common_debug("Problem getting fbuid."); + } return true; } @@ -52,6 +63,7 @@ class FbconnectauthAction extends Action if (common_is_real_login()) { $this->clientError(_('Already logged in.')); } else if ($_SERVER['REQUEST_METHOD'] == 'POST') { + $token = $this->trimmed('token'); if (!$token || $token != common_session_token()) { $this->showForm(_('There was a problem with your session token. Try again, please.')); @@ -113,7 +125,7 @@ class FbconnectauthAction extends Action $this->elementStart('form', array('method' => 'post', 'id' => 'account_connect', - 'action' => common_local_url('fbconnectlogin'))); + 'action' => common_local_url('FBConnectAuth'))); $this->hidden('token', common_session_token()); $this->element('h2', null, _('Create new account')); @@ -255,7 +267,7 @@ class FbconnectauthAction extends Action { common_debug("Trying Facebook Login..."); - $flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_SERVICE); + $flink = Foreign_link::getByForeignID($this->fbuid, FACEBOOK_CONNECT_SERVICE); if ($flink) { $user = $flink->getUser(); @@ -270,6 +282,9 @@ class FbconnectauthAction extends Action } } else { + + common_debug("no flink found for fbuid: $this->fbuid"); + $this->showForm(null, $this->bestNewNickname()); } } @@ -291,10 +306,12 @@ class FbconnectauthAction extends Action function flinkUser($user_id, $fbuid) { + common_debug("flinkUser()"); + $flink = new Foreign_link(); $flink->user_id = $user_id; $flink->foreign_id = $fbuid; - $flink->service = FACEBOOK_SERVICE; + $flink->service = FACEBOOK_CONNECT_SERVICE; $flink->created = common_sql_now(); $flink_id = $flink->insert(); diff --git a/plugins/FBConnect/FBConnectLogin.php b/plugins/FBConnect/FBConnectLogin.php index 70710eb709..7989dc854d 100644 --- a/plugins/FBConnect/FBConnectLogin.php +++ b/plugins/FBConnect/FBConnectLogin.php @@ -17,8 +17,8 @@ * along with this program. If not, see . */ -if (!defined('LACONICA')) { - exit(1); +if (!defined('LACONICA')) { + exit(1); } require_once INSTALLDIR . '/plugins/FBConnect/FBConnectPlugin.php'; @@ -31,8 +31,8 @@ class FBConnectLoginAction extends Action if (common_is_real_login()) { $this->clientError(_('Already logged in.')); - } - + } + $this->showPage(); } @@ -58,7 +58,7 @@ class FBConnectLoginAction extends Action function showContent() { $this->elementStart('fieldset'); - + $this->element('fb:login-button', array('onlogin' => 'goto_login()', 'length' => 'long')); diff --git a/plugins/FBConnect/FBConnectPlugin.php b/plugins/FBConnect/FBConnectPlugin.php index 079270510d..36dee04487 100644 --- a/plugins/FBConnect/FBConnectPlugin.php +++ b/plugins/FBConnect/FBConnectPlugin.php @@ -31,10 +31,15 @@ if (!defined('LACONICA')) { exit(1); } +define("FACEBOOK_CONNECT_SERVICE", 3); + require_once INSTALLDIR . '/lib/facebookutil.php'; require_once INSTALLDIR . '/plugins/FBConnect/FBConnectAuth.php'; require_once INSTALLDIR . '/plugins/FBConnect/FBConnectLogin.php'; +require_once INSTALLDIR . '/plugins/FBConnect/FBConnectSettings.php'; require_once INSTALLDIR . '/plugins/FBConnect/FBCLoginGroupNav.php'; +require_once INSTALLDIR . '/plugins/FBConnect/FBCSettingsNav.php'; + /** * Plugin to enable Facebook Connect @@ -56,32 +61,14 @@ class FBConnectPlugin extends Plugin // Hook in new actions function onRouterInitialized(&$m) { - - common_debug("onRouterIntialized()"); - $m->connect('main/facebookconnect', array('action' => 'FBConnectAuth')); $m->connect('main/facebooklogin', array('action' => 'FBConnectLogin')); + $m->connect('settings/facebook', array('action' => 'FBConnectSettings')); } // Add in xmlns:fb function onStartShowHTML($action) { - - // XXX: This is probably a bad place to do general processing - // so maybe I need to make some new events? Maybe in - // Action::prepare? - - $name = get_class($action); - - common_debug("onStartShowHTML: action = $name"); - - // Avoid a redirect loop - if (!in_array($name, array('FBConnectAuthAction', 'ClientErrorAction'))) { - - $this->checkFacebookUser($action); - - } - $httpaccept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : null; @@ -128,15 +115,7 @@ class FBConnectPlugin extends Plugin $apikey = common_config('facebook', 'apikey'); $plugin_path = common_path('plugins/FBConnect'); - $login_url = common_get_returnto(); - - if ($login_url) { - // We don't have to return to it again - common_set_returnto(null); - } else { - $url = common_local_url('public'); - } - + $login_url = common_local_url('FBConnectAuth'); $logout_url = common_local_url('logout'); $html = sprintf('