From 416fe67653a51087053aa3f0d4f3888207001b35 Mon Sep 17 00:00:00 2001 From: "Michael J. Rubinsky" Date: Sat, 1 May 2010 16:51:19 -0400 Subject: [PATCH] Initial attempt at refactoring facebook management for new prefs ui. --- horde/lib/Prefs/Ui.php | 169 +++++++++++++++++++++++++++++++++- horde/services/facebook.php | 142 +---------------------------- horde/templates/prefs/facebook.html | 48 ++++++++++ horde/themes/screen.css | 175 ++++++++++++++++++++++++++++++++++++ 4 files changed, 392 insertions(+), 142 deletions(-) create mode 100644 horde/templates/prefs/facebook.html diff --git a/horde/lib/Prefs/Ui.php b/horde/lib/Prefs/Ui.php index b0d62d3ce..cc87fbac5 100644 --- a/horde/lib/Prefs/Ui.php +++ b/horde/lib/Prefs/Ui.php @@ -103,7 +103,7 @@ class Horde_Prefs_Ui if (empty($conf['facebook']['enabled']) || empty($conf['facebook']['key']) || empty($conf['facebook']['secret'])) { - $ui->suppressGroups[] = 'facebook'; + //$ui->suppressGroups[] = 'facebook'; } if (empty($conf['twitter']['enabled']) || @@ -143,9 +143,12 @@ class Horde_Prefs_Ui case 'activesyncmanagement': return $this->_activesyncManagement($ui); - } + + case 'facebookmanagement': + return $this->_facebookManagement($ui); return ''; + } } /** @@ -173,6 +176,10 @@ class Horde_Prefs_Ui case 'activesyncmanagement': $this->_updateActiveSyncManagement($ui); break; + + case 'facebookmanagement': + $this->_updateFacebookManagement($ui); + break; } return false; @@ -439,6 +446,112 @@ class Horde_Prefs_Ui } /** + * Facebook session management + * + * @param Horde_Core_Prefs_Ui $ui The UI object. + * + * @return string The HTML code to display the Facebook prefs. + */ + protected function _facebookManagement($ui) + { + global $prefs; + + /* Horde_Service_Facebook */ + $GLOBALS['injector']->addBinder('Facebook', new Horde_Core_Binder_Facebook()); + try { + $facebook = $GLOBALS['injector']->getInstance('Facebook'); + } catch (Horde_Exception $e) { + return _($e->getMessage()); + } + + /* Horde_Template */ + $t = $GLOBALS['injector']->createInstance('Horde_Template'); + $t->setOption('gettext', true); + + /* Check for facebook session */ + $fbp = unserialize($prefs->getValue('facebook')); + $uid = !empty($fbp['uid']) ? $fbp['uid'] : 0; + $sid = !empty($fbp['sid']) ? $fbp['sid'] : 0; + + /* Ensure we have authorized horde */ + if (!empty($uid)) { + try { + $have_app = $facebook->users->isAppUser($uid); + } catch (Horde_Service_Facebook_Exception $e) { + return $e->getMessage(); + } + } + + /* Def. have a user that has authroized horde. See if the session key we + * have is still valid. */ + if (!empty($have_app) && !empty($sid)) { + $facebook->auth->setUser($uid, $sid, 0); + try { + /* Verify the userid matches the one we expect for the session */ + $session_uid = $facebook->auth->getLoggedInUser(); + if ($uid != $session_uid) { + // This should never happen. + $haveSession = false; + } else { + $haveSession = true; + } + } catch (Horde_Service_Facebook_Exception $e) { + $haveSession = false; + $prefs->setValue('facebook', serialize(array('uid' => $uid, 'sid' => 0))); + } + } + + /* We have a session, build the template */ + if (!empty($haveSession)) { + try { + $t->set('have_offline', + $facebook->users->hasAppPermission(Horde_Service_Facebook_Auth::EXTEND_PERMS_OFFLINE, $uid)); + $t->set('have_publish', + $facebook->users->hasAppPermission(Horde_Service_Facebook_Auth::EXTEND_PERMS_PUBLISHSTREAM, $uid)); + $t->set('have_read', + $facebook->users->hasAppPermission(Horde_Service_Facebook_Auth::EXTEND_PERMS_READSTREAM, $uid)); + } catch (Horde_Service_Facebook_Exception $e) { + $error = $e->getMessage(); + } + + /* Get the user info - facebook's TOS recommends placing the photo + * and using fb-like css for this. */ + $fql = 'SELECT first_name, last_name, status, pic_with_logo, current_location FROM user WHERE uid IN (' . $uid . ')'; + try { + $user_info = $facebook->fql->run($fql); + } catch (Horde_Service_Facebook_Exception $e) { + $notify->push(_("Temporarily unable to connect with Facebook, Please try again."), 'horde.alert'); + } + /* URL links */ + $url = Horde_Util::addParameter(Horde::selfUrl(true), array('action' => 'revokeApplication')); + $t->set('offline_url', Horde::signQueryString($url)); + $t->set('have_session', true); + $t->set('user_pic_url', $user_info[0]['pic_with_logo']); + $t->set('user_name', $user_info[0]['first_name'] . ' ' . $user_info[0]['last_name']); + + /* publish links */ + $url = $facebook->auth->getExtendedPermUrl( + Horde_Service_Facebook_Auth::EXTEND_PERMS_PUBLISHSTREAM, + Horde::url($ui->selfUrl(), true)); + $t->set('publish_url', $url); + + /* Read links */ + $url = $facebook->auth->getExtendedPermUrl( + Horde_Service_Facebook_Auth::EXTEND_PERMS_READSTREAM, + Horde::url($ui->selfUrl(), true)); + $t->set('read_url', $url); + + return $t->fetch(HORDE_TEMPLATES . '/prefs/facebook.html'); + } + + /* No existing session */ + $t->set('have_session', false); + $t->set('authUrl', $facebook->auth->getLoginUrl(Horde::url('services/facebook.php', true))); + + return $t->fetch(HORDE_TEMPLATES . '/prefs/facebook.html'); + } + + /** * Update category related preferences. * * @param Horde_Core_Prefs_Ui $ui The UI object. @@ -594,4 +707,56 @@ class Horde_Prefs_Ui } } + /** + * Update facebook related prefs + * + * @param Horde_Core_Prefs_Ui $ui The UI object. + */ + protected function _updateFacebookManagement($ui) + { + global $prefs; + + /* Horde_Service_Facebook */ + $GLOBALS['injector']->addBinder('Facebook', new Horde_Core_Binder_Facebook()); + try { + $facebook = $GLOBALS['injector']->getInstance('Facebook'); + } catch (Horde_Exception $e) { + return _($e->getMessage()); + } + switch ($ui->vars->fbactionID) { + case 'revokeInfinite': + $fbp = unserialize($prefs->getValue('facebook')); + if (!$fbp) { + // Something wrong + } + $facebook->auth->setUser($fbp['uid'], $fbp['sid']); + $facebook->auth->revokeExtendedPermission( + Horde_Service_Facebook_Auth::EXTEND_PERMS_OFFLINE, + $facebook->auth->getUser()); + break; + case 'revokeApplication': + $fbp = unserialize($prefs->getValue('facebook')); + if (!$fbp) { + // Something wrong + } + $facebook->auth->setUser($fbp['uid'], $fbp['sid']); + $facebook->auth->revokeAuthorization(); + // Clear prefs. + $prefs->setValue('facebook', array('uid' => '', + 'sid' => '')); + + break; + case 'revokePublish': + $fbp = unserialize($prefs->getValue('facebook')); + if (!$fbp) { + // Something wrong + } + $facebook->auth->setUser($fbp['uid'], $fbp['sid']); + $facebook->auth->revokeExtendedPermission( + Horde_Service_Facebook_Auth::EXTEND_PERMS_PUBLISHSTREAM, + $facebook->auth->getUser()); + break; + } + } + } diff --git a/horde/services/facebook.php b/horde/services/facebook.php index e47d2725f..fd46c5df3 100644 --- a/horde/services/facebook.php +++ b/horde/services/facebook.php @@ -37,47 +37,14 @@ if ($token = Horde_Util::getFormData('auth_token')) { $uid = $facebook->auth->getUser(); $prefs->setValue('facebook', serialize(array('uid' => $uid, 'sid' => $sid))); $notification->push(_("Succesfully connected your Facebook account."), 'horde.success'); + $url = Horde::url('services/prefs.php', true)->add(array('group' => 'facebook', 'app' => 'horde')); + header('Location: ' . $url); } } else { // Require the rest of the actions to be POST only since following them // could change the user's state. $action = Horde_Util::getPost('actionID'); - switch ($action) { - case 'revokeInfinite': - // Revoke the offline_access permission. - $fbp = unserialize($prefs->getValue('facebook')); - if (!$fbp) { - // Something wrong - } - $facebook->auth->setUser($fbp['uid'], $fbp['sid']); - $facebook->auth->revokeExtendedPermission( - Horde_Service_Facebook_Auth::EXTEND_PERMS_OFFLINE, - $facebook->auth->getUser()); - break; - - case 'revokeApplication': - $fbp = unserialize($prefs->getValue('facebook')); - if (!$fbp) { - // Something wrong - } - $facebook->auth->setUser($fbp['uid'], $fbp['sid']); - $facebook->auth->revokeAuthorization(); - // Clear prefs. - $prefs->setValue('facebook', array('uid' => '', - 'sid' => '')); - - break; - case 'revokePublish': - $fbp = unserialize($prefs->getValue('facebook')); - if (!$fbp) { - // Something wrong - } - $facebook->auth->setUser($fbp['uid'], $fbp['sid']); - $facebook->auth->revokeExtendedPermission( - Horde_Service_Facebook_Auth::EXTEND_PERMS_PUBLISHSTREAM, - $facebook->auth->getUser()); - break; case 'updateStatus': // Set the user's status $fbp = unserialize($prefs->getValue('facebook')); @@ -170,108 +137,3 @@ if (!empty($have_app) && !empty($sid)) { } } -// If we have a good session, see about our extended permissions -if (!empty($haveSession)) { - try { - $have_offline = $facebook->users->hasAppPermission( - Horde_Service_Facebook_Auth::EXTEND_PERMS_OFFLINE, $uid); - $have_publish = $facebook->users->hasAppPermission( - Horde_Service_Facebook_Auth::EXTEND_PERMS_PUBLISHSTREAM, $uid); - $have_read = $facebook->users->hasAppPermission( - Horde_Service_Facebook_Auth::EXTEND_PERMS_READSTREAM, $uid); - } catch (Horde_Service_Facebook_Exception $e) { - $error = $e->getMessage(); - } -} - -// Start rendering the prefs page -// TODO: This won't work - prefs handling must be moved to the new -// preferences framework. -//$csslink = $registry->get('themesuri', 'horde') . '/facebook.css'; - -if (!empty($haveSession)) { - // If we are here, we have a valid session. Facebook strongly suggests to - // place the user's profile picture with the small Facebook icon on it, - // along with the user's full name (as it appears on Facebook) on the page - // to clarify this to the user. They also suggest using Facebook CSS rules - // for Facebook related notices and content. - $fql = 'SELECT first_name, last_name, status, pic_with_logo, current_location FROM user WHERE uid IN (' . $uid . ')'; - - try { - $user_info = $facebook->fql->run($fql); - } catch (Horde_Service_Facebook_Exception $e) { - $notify->push(_("Temporarily unable to connect with Facebook, Please try again."), 'horde.alert'); - } - // url to revoke authorization - $url = Horde_Util::addParameter(Horde::selfUrl(true), array('action' => 'revokeApplication')); - $url = Horde::signQueryString($url); - - echo '
'; - echo ''; - echo '' . $user_info[0]['first_name'] . ' ' . $user_info[0]['last_name'] . ''; - echo '
'; - echo '
 
'; - - // Offline access links - if (!empty($have_app) && empty($have_offline) ) { - // Url for offline_access perms - $url = $facebook->auth->getExtendedPermUrl( - Horde_Service_Facebook_Auth::EXTEND_PERMS_OFFLINE, - Horde_Util::addParameter(Horde::url('services/facebook.php', true), 'action', 'authsuccess')); - - echo '
' - . sprintf(_("%s can interact with your Facebook account, but you must login to Facebook manually each time."), $registry->get('name')) - . '
' . _("Authorize an infinite session") - . ': Facebook
'; - - } elseif (!empty($have_app)) { - // Have offline_access, provide a means to revoke it from within Horde - echo '
' - . _("Infinite sessions enabled.") - . '
'; - } - - // Publish links - if (!empty($have_publish)) { - // Auth'd the publish API. - echo '
' . _("Publish enabled.") - . '
'; - } else { - $url = $facebook->auth->getExtendedPermUrl( - Horde_Service_Facebook_Auth::EXTEND_PERMS_PUBLISHSTREAM, - Horde::url('services/facebook.php', true)); - echo '
' - . sprintf(_("%s cannot set your status messages or publish other content to Facebook."), $registry->get('name')) - . '
' - . _("Authorize Publish:") - . ' Facebook
'; - } - - // Read links - if (!empty($have_read)) { - echo '
' . _("Read enabled.") - . '
'; - } else { - $url = $facebook->auth->getExtendedPermUrl( - Horde_Service_Facebook_Auth::EXTEND_PERMS_READSTREAM, - Horde::url('services/facebook.php', true)); - echo '
' - . sprintf(_("%s cannot read your stream messages."), $registry->get('name')) - . '
' - . _("Authorize Read:") - . ' Facebook
'; - } - -} else { - // No valid session information at all - echo '
' - . sprintf(_("Could not find authorization for %s to interact with your Facebook account."), $registry->get('name')) - . '
'; - $url = $facebook->auth->getLoginUrl(Horde::url('services/facebook.php', true)); - - if (!empty($error)) { - echo $error; - } - echo sprintf(_("Login to Facebook and authorize the %s application:"), $registry->get('name')) - . 'Facebook'; -} diff --git a/horde/templates/prefs/facebook.html b/horde/templates/prefs/facebook.html new file mode 100644 index 000000000..755a2600b --- /dev/null +++ b/horde/templates/prefs/facebook.html @@ -0,0 +1,48 @@ + + +
+ + +
+
 
+ +
Infinite sessions enabled. +
+
+ +
+ can interact with your Facebook account, but you must login to Facebook manually each time. +
Authorize an infinite session:Facebook
+
+
+
+ +
Publish enabled. +
+
+ +
+ cannot set your status messages or publish other content to Facebook. +
Authorize Publish:Facebook
+
+
+
+ +
+ Read enabled +
+
+ +
+ cannot read your stream messages. +
Authorize Read:Facebook
+
+
+
+ +
Could not find authorization for to interact with your Facebook account.
+
+ Login to Facebook and authorize + Facebook +
+
\ No newline at end of file diff --git a/horde/themes/screen.css b/horde/themes/screen.css index 5df01ae3a..62d17d59c 100644 --- a/horde/themes/screen.css +++ b/horde/themes/screen.css @@ -1199,3 +1199,178 @@ div.GrowlerNoticeExit:hover { display: none !important; } } + +* Default Facebook CSS */ +.fbbody, .fbaction +{ + font-family: "lucida grande" ,tahoma,verdana,arial,sans-serif; + font-size: 11px; + color: #333333; +} +/* Default Anchor Style */ +.fbbody a +{ + color: #3b5998; + outline-style: none; + text-decoration: none; + font-size: 11px; + font-weight: bold; +} + +.fbaction a, .fbaction input +{ + color: #ffffff; + outline-style: none; + text-decoration: none; + font-size: 11px; + font-weight: bold; +} + +.fbbody a:hover +{ + text-decoration: underline; +} +/* Facebook Box Styles */ +.fbgreybox +{ + background-color: #f7f7f7; + border: 1px solid #cccccc; + color: #333333; + padding: 10px; + font-size: 13px; + font-weight: bold; +} +.fbbluebox +{ + background-color: #eceff6; + border: 1px solid #d4dae8; + color: #333333; + padding: 10px; + font-size: 13px; + font-weight: bold; +} +.fbinfobox +{ + background-color: #fff9d7; + border: 1px solid #e2c822; + color: #333333; + padding: 10px; + font-size: 13px; + font-weight: bold; +} +.fberrorbox +{ + background-color: #ffebe8; + border: 1px solid #dd3c10; + color: #333333; + padding: 10px; + font-size: 13px; + font-weight: bold; +} +/* Content Divider on White Background */ +.fbcontentdivider +{ + margin-top: 2px; + margin-bottom: 2px; + margin-right: 4px; + margin-left: 4px; + height: 1px; + background-color: #d8dfea; +} +/* Facebook Tab Style */ +.fbtab +{ + padding: 8px; + background-color: #d8dfea; + color: #3b5998; + font-weight: bold; + float: left; + margin-right: 4px; + text-decoration: none; +} +.fbtab:hover +{ + background-color: #3b5998; + color: #ffffff; + cursor: hand; +} +.fbbutton { + background-color:#3B5998; + border-color:#D9DFEA #0E1F5B #0E1F5B #D9DFEA; + border-style:solid; + border-width:1px; + color:#FFFFFF; + font-family:"lucida grande",tahoma,verdana,arial,sans-serif; + font-size:11px; + padding:2px 15px 3px; + cursor: pointer; + text-align:center; +} +.fbbutton:hover { + text-decoration: underline; +} + +.fbbutton:focus, a.fbbutton:hover, a.fbbutton:focus { + background: #3B5998; +} + +/* Stream css */ +.fbstreamstory { + margin-bottom: 7px; + padding-top: 7px; + position: relative; +} +.fbstreampic { + display: inline; + height: 50px; + width: 50px; +} +.fbstreambody { + padding: 0 0 0 60px; + min-height: 60px; +} +.fbstreaminfo { + color: #777777; + padding: 2px 0 0; + font-style: italic; +} + +.fbattachment { + margin-top: 6px; + overflow: hidden; +} +.fbattachmenttitle { + font-weight: bold; +} +.fbattachmentcaption, .fbattachmentcopy{ + color: gray; + padding-top: 3px; +} + +.fbmedia { + float: left; + overflow: hidden; +} +.fbmediawide { + float: none; +} +.fbmediaitem { + float: left; +} +.fbmediaitem img { + display: block; + vertical-align: middle; + max-height: 200px; + max-width: 130px; +} +.fbmediaitemsingle { + padding-right:5px; +} +.fbmediaitemmultiple { + padding-left: 5px; +} + +.fbemptystatus { + font-style: italic; + color: gray; +} -- 2.11.0