]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge commit 'origin/testing' into 0.9.x
authorBrion Vibber <brion@pobox.com>
Thu, 4 Mar 2010 14:07:28 +0000 (06:07 -0800)
committerBrion Vibber <brion@pobox.com>
Thu, 4 Mar 2010 14:07:28 +0000 (06:07 -0800)
Conflicts:
lib/action.php
lib/adminpanelaction.php

1  2 
classes/File.php
classes/User.php
classes/User_group.php
index.php
lib/action.php
lib/adminpanelaction.php
lib/default.php
plugins/Facebook/FacebookPlugin.php
plugins/OStatus/OStatusPlugin.php

diff --combined classes/File.php
index 79a7d6681334e881144a3194fe567ea8a2ae3201,1b8ef1b3eea15f957b82736a38e6e73838355e94..4ecd3b959aa9aaef12f4e459decbb173b8f0f7a6
@@@ -169,11 -169,7 +169,11 @@@ class File extends Memcached_DataObjec
      {
          require_once 'MIME/Type/Extension.php';
          $mte = new MIME_Type_Extension();
 -        $ext = $mte->getExtension($mimetype);
 +        try {
 +            $ext = $mte->getExtension($mimetype);
 +        } catch ( Exception $e) {
 +            $ext = strtolower(preg_replace('/\W/', '', $mimetype));
 +        }
          $nickname = $profile->nickname;
          $datestamp = strftime('%Y%m%dT%H%M%S', time());
          $random = strtolower(common_confirmation_code(32));
          }
          return $enclosure;
      }
+     // quick back-compat hack, since there's still code using this
+     function isEnclosure()
+     {
+         $enclosure = $this->getEnclosure();
+         return !empty($enclosure);
+     }
  }
  
diff --combined classes/User.php
index 357c1e501343ed324d3de3eb5aa1780dd394be00,aa9fbf94838f3b64427efdc4196b74c3a4624fce..fade0f35deaa28f930c346fa4c80a21d3e0d4d4f
@@@ -206,7 -206,6 +206,7 @@@ class User extends Memcached_DataObjec
          if(! User::allowed_nickname($nickname)){
              common_log(LOG_WARNING, sprintf("Attempted to register a nickname that is not allowed: %s", $profile->nickname),
                         __FILE__);
 +            return false;
          }
          $profile->profileurl = common_profile_url($nickname);
  
  
      function getGroups($offset=0, $limit=null)
      {
-         $qry =
-           'SELECT user_group.* ' .
-           'FROM user_group JOIN group_member '.
-           'ON user_group.id = group_member.group_id ' .
-           'WHERE group_member.profile_id = %d ' .
-           'ORDER BY group_member.created DESC ';
-         if ($offset>0 && !is_null($limit)) {
-             if ($offset) {
-                 if (common_config('db','type') == 'pgsql') {
-                     $qry .= ' LIMIT ' . $limit . ' OFFSET ' . $offset;
-                 } else {
-                     $qry .= ' LIMIT ' . $offset . ', ' . $limit;
-                 }
-             }
-         }
-         $groups = new User_group();
-         $cnt = $groups->query(sprintf($qry, $this->id));
-         return $groups;
+         $profile = $this->getProfile();
+         return $profile->getGroups($offset, $limit);
      }
  
      function getSubscriptions($offset=0, $limit=null)
diff --combined classes/User_group.php
index e9288747467472491459be7b6c72868557040107,0460c9870a34cb318ed1c21a34429ea46059720e..7be55163a30186c0199f1ffc36dc82692b370089
@@@ -279,12 -279,26 +279,26 @@@ class User_group extends Memcached_Data
          return true;
      }
  
-     static function getForNickname($nickname)
+     static function getForNickname($nickname, $profile=null)
      {
          $nickname = common_canonical_nickname($nickname);
-         $group = User_group::staticGet('nickname', $nickname);
+         // Are there any matching remote groups this profile's in?
+         if ($profile) {
+             $group = $profile->getGroups();
+             while ($group->fetch()) {
+                 if ($group->nickname == $nickname) {
+                     // @fixme is this the best way?
+                     return clone($group);
+                 }
+             }
+         }
+         // If not, check local groups.
+     
+         $group = Local_group::staticGet('nickname', $nickname);
          if (!empty($group)) {
-             return $group;
+             return User_group::staticGet('id', $group->group_id);
          }
          $alias = Group_alias::staticGet('alias', $nickname);
          if (!empty($alias)) {
          $group = new User_group();
  
          $group->query('BEGIN');
+         
+         if (empty($uri)) {
+             // fill in later...
+             $uri = null;
+         }
  
          $group->nickname    = $nickname;
          $group->fullname    = $fullname;
              $result = $group->update($orig);
              if (!$result) {
                  common_log_db_error($group, 'UPDATE', __FILE__);
 -                throw new ServerException(_('Could not set group uri.'));
 +                throw new ServerException(_('Could not set group URI.'));
              }
          }
  
diff --combined index.php
index 215d1f676e1f28dca36c2ae360fef123a6665097,36ba3a0d2163915fa700ef0373b5ee65fa317c63..65f251bcce6144db63bf3e6870fbda4d311da0fb
+++ b/index.php
@@@ -37,6 -37,8 +37,6 @@@ define('INSTALLDIR', dirname(__FILE__))
  define('STATUSNET', true);
  define('LACONICA', true); // compatibility
  
 -require_once INSTALLDIR . '/lib/common.php';
 -
  $user = null;
  $action = null;
  
@@@ -66,69 -68,52 +66,69 @@@ function getPath($req
   */
  function handleError($error)
  {
 -    if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) {
 -        return;
 -    }
 +    try {
  
 -    $logmsg = "PEAR error: " . $error->getMessage();
 -    if (common_config('site', 'logdebug')) {
 -        $logmsg .= " : ". $error->getDebugInfo();
 -    }
 -    // DB queries often end up with a lot of newlines; merge to a single line
 -    // for easier grepability...
 -    $logmsg = str_replace("\n", " ", $logmsg);
 -    common_log(LOG_ERR, $logmsg);
 -
 -    // @fixme backtrace output should be consistent with exception handling
 -    if (common_config('site', 'logdebug')) {
 -        $bt = $error->getBacktrace();
 -        foreach ($bt as $n => $line) {
 -            common_log(LOG_ERR, formatBacktraceLine($n, $line));
 +        if ($error->getCode() == DB_DATAOBJECT_ERROR_NODATA) {
 +            return;
          }
 -    }
 -    if ($error instanceof DB_DataObject_Error
 -        || $error instanceof DB_Error
 -    ) {
 -        $msg = sprintf(
 -            _(
 -                'The database for %s isn\'t responding correctly, '.
 -                'so the site won\'t work properly. '.
 -                'The site admins probably know about the problem, '.
 -                'but you can contact them at %s to make sure. '.
 -                'Otherwise, wait a few minutes and try again.'
 -            ),
 -            common_config('site', 'name'),
 -            common_config('site', 'email')
 -        );
 -    } else {
 -        $msg = _(
 -            'An important error occured, probably related to email setup. '.
 -            'Check logfiles for more info..'
 -        );
 -    }
  
 -    $dac = new DBErrorAction($msg, 500);
 -    $dac->showPage();
 +        $logmsg = "PEAR error: " . $error->getMessage();
 +        if ($error instanceof PEAR_Exception && common_config('site', 'logdebug')) {
 +            $logmsg .= " : ". $error->toText();
 +        }
 +        // DB queries often end up with a lot of newlines; merge to a single line
 +        // for easier grepability...
 +        $logmsg = str_replace("\n", " ", $logmsg);
 +        common_log(LOG_ERR, $logmsg);
 +
 +        // @fixme backtrace output should be consistent with exception handling
 +        if (common_config('site', 'logdebug')) {
 +            $bt = $error->getTrace();
 +            foreach ($bt as $n => $line) {
 +                common_log(LOG_ERR, formatBacktraceLine($n, $line));
 +            }
 +        }
 +        if ($error instanceof DB_DataObject_Error
 +            || $error instanceof DB_Error
 +            || ($error instanceof PEAR_Exception && $error->getCode() == -24)
 +        ) {
 +            //If we run into a DB error, assume we can't connect to the DB at all
 +            //so set the current user to null, so we don't try to access the DB
 +            //while rendering the error page.
 +            global $_cur;
 +            $_cur = null;
 +
 +            $msg = sprintf(
 +                _(
 +                    'The database for %s isn\'t responding correctly, '.
 +                    'so the site won\'t work properly. '.
 +                    'The site admins probably know about the problem, '.
 +                    'but you can contact them at %s to make sure. '.
 +                    'Otherwise, wait a few minutes and try again.'
 +                ),
 +                common_config('site', 'name'),
 +                common_config('site', 'email')
 +            );
 +        } else {
 +            $msg = _(
 +                'An important error occured, probably related to email setup. '.
 +                'Check logfiles for more info..'
 +            );
 +        }
 +
 +        $dac = new DBErrorAction($msg, 500);
 +        $dac->showPage();
 +
 +    } catch (Exception $e) {
 +        echo _('An error occurred.');
 +    }
      exit(-1);
  }
  
 +set_exception_handler('handleError');
 +
 +require_once INSTALLDIR . '/lib/common.php';
 +
  /**
   * Format a backtrace line for debug output roughly like debug_print_backtrace() does.
   * Exceptions already have this built in, but PEAR error objects just give us the array.
@@@ -200,7 -185,7 +200,7 @@@ function checkMirror($action_obj, $args
  
  function isLoginAction($action)
  {
-     static $loginActions =  array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds');
+     static $loginActions =  array('login', 'recoverpassword', 'api', 'doc', 'register', 'publicxrds', 'otp');
  
      $login = null;
  
@@@ -253,6 -238,10 +253,6 @@@ function main(
          return;
      }
  
 -    // For database errors
 -
 -    PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, 'handleError');
 -
      // Make sure RW database is setup
  
      setupRW();
diff --combined lib/action.php
index a804b8e82536ac0d3cbdddeb3d6bce0880919e73,816086d202f00889f686d31a228ac1e5049b5d49..10394c78956775490e1365cc31b19f4958b0693d
@@@ -420,84 -420,45 +420,75 @@@ class Action extends HTMLOutputter // l
      function showPrimaryNav()
      {
          $user = common_current_user();
-         $connect = '';
-         if (common_config('xmpp', 'enabled')) {
-             $connect = 'imsettings';
-         } else if (common_config('sms', 'enabled')) {
-             $connect = 'smssettings';
-         }
          $this->elementStart('dl', array('id' => 'site_nav_global_primary'));
          $this->element('dt', null, _('Primary site navigation'));
          $this->elementStart('dd');
          $this->elementStart('ul', array('class' => 'nav'));
          if (Event::handle('StartPrimaryNav', array($this))) {
              if ($user) {
 +                // TRANS: Tooltip for main menu option "Personal"
 +                $tooltip = _m('TOOLTIP', 'Personal profile and friends timeline');
 +                // TRANS: Main menu option when logged in for access to personal profile and friends timeline
                  $this->menuItem(common_local_url('all', array('nickname' => $user->nickname)),
 -                                _('Home'), _('Personal profile and friends timeline'), false, 'nav_home');
 +                                _m('MENU', 'Personal'), $tooltip, false, 'nav_home');
 +                // TRANS: Tooltip for main menu option "Account"
 +                $tooltip = _m('TOOLTIP', 'Change your email, avatar, password, profile');
 +                // TRANS: Main menu option when logged in for access to user settings
                  $this->menuItem(common_local_url('profilesettings'),
-                                 _m('MENU', 'Account'), $tooltip, false, 'nav_account');
-                 if ($connect) {
-                     // TRANS: Tooltip for main menu option "Services"
-                     $tooltip = _m('TOOLTIP', 'Connect to services');
-                     // TRANS: Main menu option when logged in and connection are possible for access to options to connect to other services
-                     $this->menuItem(common_local_url($connect),
-                                     _m('MENU', 'Connect'), $tooltip, false, 'nav_connect');
-                 }
 -                                _('Account'), _('Change your email, avatar, password, profile'), false, 'nav_account');
++                                _('Account'), $tooltip, false, 'nav_account');
++                // TRANS: Tooltip for main menu option "Services"
++                $tooltip = _m('TOOLTIP', 'Connect to services');
++                // TRANS: Main menu option when logged in and connection are possible for access to options to connect to other services
+                 $this->menuItem(common_local_url('oauthconnectionssettings'),
 -                                _('Connect'), _('Connect to services'), false, 'nav_connect');
++                                _('Connect'), $tooltip, false, 'nav_connect');
                  if ($user->hasRight(Right::CONFIGURESITE)) {
 +                    // TRANS: Tooltip for menu option "Admin"
 +                    $tooltip = _m('TOOLTIP', 'Change site configuration');
 +                    // TRANS: Main menu option when logged in and site admin for access to site configuration
                      $this->menuItem(common_local_url('siteadminpanel'),
 -                                    _('Admin'), _('Change site configuration'), false, 'nav_admin');
 +                                    _m('MENU', 'Admin'), $tooltip, false, 'nav_admin');
                  }
                  if (common_config('invite', 'enabled')) {
 +                    // TRANS: Tooltip for main menu option "Invite"
 +                    $tooltip = _m('TOOLTIP', 'Invite friends and colleagues to join you on %s');
 +                    // TRANS: Main menu option when logged in and invitations are allowed for inviting new users
                      $this->menuItem(common_local_url('invite'),
 -                                    _('Invite'),
 -                                    sprintf(_('Invite friends and colleagues to join you on %s'),
 +                                    _m('MENU', 'Invite'),
 +                                    sprintf($tooltip,
                                              common_config('site', 'name')),
                                      false, 'nav_invitecontact');
                  }
 +                // TRANS: Tooltip for main menu option "Logout"
 +                $tooltip = _m('TOOLTIP', 'Logout from the site');
 +                // TRANS: Main menu option when logged in to log out the current user
                  $this->menuItem(common_local_url('logout'),
 -                                _('Logout'), _('Logout from the site'), false, 'nav_logout');
 +                                _m('MENU', 'Logout'), $tooltip, false, 'nav_logout');
              }
              else {
                  if (!common_config('site', 'closed')) {
 +                    // TRANS: Tooltip for main menu option "Register"
 +                    $tooltip = _m('TOOLTIP', 'Create an account');
 +                    // TRANS: Main menu option when not logged in to register a new account
                      $this->menuItem(common_local_url('register'),
 -                                    _('Register'), _('Create an account'), false, 'nav_register');
 +                                    _m('MENU', 'Register'), $tooltip, false, 'nav_register');
                  }
 +                // TRANS: Tooltip for main menu option "Login"
 +                $tooltip = _m('TOOLTIP', 'Login to the site');
 +                // TRANS: Main menu option when not logged in to log in
                  $this->menuItem(common_local_url('login'),
 -                                _('Login'), _('Login to the site'), false, 'nav_login');
 +                                _m('MENU', 'Login'), $tooltip, false, 'nav_login');
              }
 +            // TRANS: Tooltip for main menu option "Help"
 +            $tooltip = _m('TOOLTIP', 'Help me!');
 +            // TRANS: Main menu option for help on the StatusNet site
              $this->menuItem(common_local_url('doc', array('title' => 'help')),
 -                            _('Help'), _('Help me!'), false, 'nav_help');
 +                            _m('MENU', 'Help'), $tooltip, false, 'nav_help');
              if ($user || !common_config('site', 'private')) {
 +                // TRANS: Tooltip for main menu option "Search"
 +                $tooltip = _m('TOOLTIP', 'Search for people or text');
 +                // TRANS: Main menu option when logged in or when the StatusNet instance is not private
                  $this->menuItem(common_local_url('peoplesearch'),
 -                                _('Search'), _('Search for people or text'), false, 'nav_search');
 +                                _m('MENU', 'Search'), $tooltip, false, 'nav_search');
              }
              Event::handle('EndPrimaryNav', array($this));
          }
          if ($text) {
              $this->elementStart('dl', array('id' => 'site_notice',
                                              'class' => 'system_notice'));
 +            // TRANS: DT element for site notice. String is hidden in default CSS.
              $this->element('dt', null, _('Site notice'));
              $this->elementStart('dd', null);
              $this->raw($text);
diff --combined lib/adminpanelaction.php
index a0cdab8a45dc9bb29e000369b1acc002d1e4310f,d1aab3dfcbadc8e4dad3d5c24d78a174b178c96a..f3f86449f3096681423da372576743a95fd2c8a1
@@@ -69,7 -69,6 +69,7 @@@ class AdminPanelAction extends Actio
          // User must be logged in.
  
          if (!common_logged_in()) {
 +            // TRANS: Client error message
              $this->clientError(_('Not logged in.'));
              return false;
          }
@@@ -94,7 -93,6 +94,7 @@@
          // User must have the right to change admin settings
  
          if (!$user->hasRight(Right::CONFIGURESITE)) {
 +            // TRANS: Client error message
              $this->clientError(_('You cannot make changes to this site.'));
              return false;
          }
          $name = mb_substr($name, 0, -10);
  
          if (!self::canAdmin($name)) {
 +            // TRANS: Client error message
              $this->clientError(_('Changes to that panel are not allowed.'), 403);
              return false;
          }
                  Config::loadSettings();
  
                  $this->success = true;
 +                // TRANS: Message after successful saving of administrative settings.
                  $this->msg     = _('Settings saved.');
              } catch (Exception $e) {
                  $this->success = false;
          $this->showForm();
      }
  
+     /**
+      * Show content block. Overrided just to add a special class
+      * to the content div to allow styling.
+      *
+      * @return nothing
+      */
+     function showContentBlock()
+     {
+         $this->elementStart('div', array('id' => 'content', 'class' => 'admin'));
+         $this->showPageTitle();
+         $this->showPageNoticeBlock();
+         $this->elementStart('div', array('id' => 'content_inner'));
+         // show the actual content (forms, lists, whatever)
+         $this->showContent();
+         $this->elementEnd('div');
+         $this->elementEnd('div');
+     }
+     /**
+      * There is no data for aside, so, we don't output
+      *
+      * @return nothing
+      */
+     function showAside()
+     {
+     }
      /**
       * show human-readable instructions for the page, or
       * a success/failure on save.
  
      function showForm()
      {
 +        // TRANS: Client error message
          $this->clientError(_('showForm() not implemented.'));
          return;
      }
  
      function saveSettings()
      {
 +        // TRANS: Client error message
          $this->clientError(_('saveSettings() not implemented.'));
          return;
      }
              $result = $config->delete();
              if (!$result) {
                  common_log_db_error($config, 'DELETE', __FILE__);
 +                // TRANS: Client error message
                  $this->clientError(_("Unable to delete design setting."));
                  return null;
              }
@@@ -326,51 -347,43 +354,67 @@@ class AdminPanelNav extends Widge
          if (Event::handle('StartAdminPanelNav', array($this))) {
  
              if (AdminPanelAction::canAdmin('site')) {
 -                $this->out->menuItem(common_local_url('siteadminpanel'), _('Site'),
 -                                     _('Basic site configuration'), $action_name == 'siteadminpanel', 'nav_site_admin_panel');
 +                // TRANS: Menu item title/tooltip
 +                $menu_title = _('Basic site configuration');
 +                // TRANS: Menu item for site administration
 +                $this->out->menuItem(common_local_url('siteadminpanel'), _m('MENU', 'Site'),
 +                                     $menu_title, $action_name == 'siteadminpanel', 'nav_site_admin_panel');
              }
  
              if (AdminPanelAction::canAdmin('design')) {
 -                $this->out->menuItem(common_local_url('designadminpanel'), _('Design'),
 -                                     _('Design configuration'), $action_name == 'designadminpanel', 'nav_design_admin_panel');
 +                // TRANS: Menu item title/tooltip
 +                $menu_title = _('Design configuration');
 +                // TRANS: Menu item for site administration
 +                $this->out->menuItem(common_local_url('designadminpanel'), _m('MENU', 'Design'),
 +                                     $menu_title, $action_name == 'designadminpanel', 'nav_design_admin_panel');
              }
  
              if (AdminPanelAction::canAdmin('user')) {
-                 $this->out->menuItem(common_local_url('useradminpanel'), _m('MENU', 'User'),
-                                      $menu_title, $action_name == 'useradminpanel', 'nav_design_admin_panel');
 +                // TRANS: Menu item title/tooltip
 +                $menu_title = _('User configuration');
 +                // TRANS: Menu item for site administration
 -                                     _('User configuration'), $action_name == 'useradminpanel', 'nav_user_admin_panel');
+                 $this->out->menuItem(common_local_url('useradminpanel'), _('User'),
++                                     $menu_title, $action_name == 'useradminpanel', 'nav_user_admin_panel');
              }
  
              if (AdminPanelAction::canAdmin('access')) {
-                 $this->out->menuItem(common_local_url('accessadminpanel'), _m('MENU', 'Access'),
-                                      $menu_title, $action_name == 'accessadminpanel', 'nav_design_admin_panel');
 +                // TRANS: Menu item title/tooltip
 +                $menu_title = _('Access configuration');
 +                // TRANS: Menu item for site administration
 -                                     _('Access configuration'), $action_name == 'accessadminpanel', 'nav_access_admin_panel');
+                 $this->out->menuItem(common_local_url('accessadminpanel'), _('Access'),
++                                     $menu_title, $action_name == 'accessadminpanel', 'nav_access_admin_panel');
              }
  
              if (AdminPanelAction::canAdmin('paths')) {
-                 $this->out->menuItem(common_local_url('pathsadminpanel'), _m('MENU', 'Paths'),
-                                     $menu_title, $action_name == 'pathsadminpanel', 'nav_design_admin_panel');
 +                // TRANS: Menu item title/tooltip
 +                $menu_title = _('Paths configuration');
 +                // TRANS: Menu item for site administration
 -                                    _('Paths configuration'), $action_name == 'pathsadminpanel', 'nav_paths_admin_panel');
+                 $this->out->menuItem(common_local_url('pathsadminpanel'), _('Paths'),
++                                    $menu_title, $action_name == 'pathsadminpanel', 'nav_paths_admin_panel');
              }
  
              if (AdminPanelAction::canAdmin('sessions')) {
-                 $this->out->menuItem(common_local_url('sessionsadminpanel'), _m('MENU', 'Sessions'),
-                                      $menu_title, $action_name == 'sessionsadminpanel', 'nav_design_admin_panel');
 +                // TRANS: Menu item title/tooltip
 +                $menu_title = _('Sessions configuration');
 +                // TRANS: Menu item for site administration
 -                                     _('Sessions configuration'), $action_name == 'sessionsadminpanel', 'nav_sessions_admin_panel');
+                 $this->out->menuItem(common_local_url('sessionsadminpanel'), _('Sessions'),
 -                                     _('Edit site notice'), $action_name == 'sitenoticeadminpanel', 'nav_sitenotice_admin_panel');
++                                     $menu_title, $action_name == 'sessionsadminpanel', 'nav_sessions_admin_panel');
+             }
+             if (AdminPanelAction::canAdmin('sitenotice')) {
++                // TRANS: Menu item title/tooltip
++                $menu_title = _('Edit site notice');
++                // TRANS: Menu item for site administration
+                 $this->out->menuItem(common_local_url('sitenoticeadminpanel'), _('Site notice'),
 -                                     _('Snapshots configuration'), $action_name == 'snapshotadminpanel', 'nav_snapshot_admin_panel');
++                                     $menu_title, $action_name == 'sitenoticeadminpanel', 'nav_sitenotice_admin_panel');
+             }
+             if (AdminPanelAction::canAdmin('snapshot')) {
++                // TRANS: Menu item title/tooltip
++                $menu_title = _('Snapshots configuration');
++                // TRANS: Menu item for site administration
+                 $this->out->menuItem(common_local_url('snapshotadminpanel'), _('Snapshots'),
++                                     $menu_title, $action_name == 'snapshotadminpanel', 'nav_snapshot_admin_panel');
              }
  
              Event::handle('EndAdminPanelNav', array($this));
diff --combined lib/default.php
index 7b97c7dda874d5470a7a35039d34bec70c036295,8e99a0e1c31727ace1e25c8750beb677517b63a5..c46c3eef57abd7d8b5e12f6e5c15ddf8a2992305
@@@ -40,7 -40,8 +40,8 @@@ $default 
                'logdebug' => false,
                'fancy' => false,
                'locale_path' => INSTALLDIR.'/locale',
-               'language' => 'en_US',
+               'language' => 'en',
+               'langdetect' => true,
                'languages' => get_all_languages(),
                'email' =>
                array_key_exists('SERVER_ADMIN', $_SERVER) ? $_SERVER['SERVER_ADMIN'] : null,
                'ssl' => 'never',
                'sslserver' => null,
                'shorturllength' => 30,
-               'dupelimit' => 60, # default for same person saying the same thing
+               'dupelimit' => 60, // default for same person saying the same thing
                'textlimit' => 140,
                'indent' => true,
-               'use_x_sendfile' => false
+               'use_x_sendfile' => false,
+               'notice' => null // site wide notice text
                ),
          'db' =>
          array('database' => 'YOU HAVE TO SET THIS IN config.php',
                                   'Geonames' => null,
                                   'Mapstraction' => null,
                                   'WikiHashtags' => null,
 +                                 'RSSCloud' => null,
                                   'OpenID' => null),
                ),
          'admin' =>
-         array('panels' => array('design', 'site', 'user', 'paths', 'access', 'sessions')),
+         array('panels' => array('design', 'site', 'user', 'paths', 'access', 'sessions', 'sitenotice')),
          'singleuser' =>
          array('enabled' => false,
                'nickname' => null),
index 443cb396fcc5107f8e2a10f52a559758c934f97b,65d4409b5e44db258abef59163ebcbcab79e0adf..5dba73a5d8574a63f63c852229ae15a0b478b739
@@@ -79,6 -79,25 +79,25 @@@ class FacebookPlugin extends Plugi
          }
      }
  
+     /**
+      * Check to see if there is an API key and secret defined
+      * for Facebook integration.
+      *
+      * @return boolean result
+      */
+     static function hasKeys()
+     {
+         $apiKey    = common_config('facebook', 'apikey');
+         $apiSecret = common_config('facebook', 'secret');
+         if (!empty($apiKey) && !empty($apiSecret)) {
+             return true;
+         }
+         return false;
+     }
      /**
       * Add Facebook app actions to the router table
       *
  
      function onStartInitializeRouter($m)
      {
+         $m->connect('admin/facebook', array('action' => 'facebookadminpanel'));
  
-         // Facebook App stuff
+         if (self::hasKeys()) {
  
-         $m->connect('facebook/app', array('action' => 'facebookhome'));
-         $m->connect('facebook/app/index.php', array('action' => 'facebookhome'));
-         $m->connect('facebook/app/settings.php',
-                     array('action' => 'facebooksettings'));
-         $m->connect('facebook/app/invite.php', array('action' => 'facebookinvite'));
-         $m->connect('facebook/app/remove', array('action' => 'facebookremove'));
-         $m->connect('admin/facebook', array('action' => 'facebookadminpanel'));
+             // Facebook App stuff
  
-         // Facebook Connect stuff
+             $m->connect('facebook/app', array('action' => 'facebookhome'));
+             $m->connect('facebook/app/index.php', array('action' => 'facebookhome'));
+             $m->connect('facebook/app/settings.php',
+                         array('action' => 'facebooksettings'));
+             $m->connect('facebook/app/invite.php', array('action' => 'facebookinvite'));
+             $m->connect('facebook/app/remove', array('action' => 'facebookremove'));
  
-         $m->connect('main/facebookconnect', array('action' => 'FBConnectAuth'));
-         $m->connect('main/facebooklogin', array('action' => 'FBConnectLogin'));
-         $m->connect('settings/facebook', array('action' => 'FBConnectSettings'));
-         $m->connect('xd_receiver.html', array('action' => 'FBC_XDReceiver'));
+             // Facebook Connect stuff
+             $m->connect('main/facebookconnect', array('action' => 'FBConnectAuth'));
+             $m->connect('main/facebooklogin', array('action' => 'FBConnectLogin'));
+             $m->connect('settings/facebook', array('action' => 'FBConnectSettings'));
+             $m->connect('xd_receiver.html', array('action' => 'FBC_XDReceiver'));
+         }
  
          return true;
      }
          if ($this->reqFbScripts($action)) {
  
              $apikey      = common_config('facebook', 'apikey');
 -            $plugin_path = common_path('plugins/Facebook');
 +            $plugin_path = 'plugins/Facebook';
  
              $login_url  = common_local_url('FBConnectAuth');
              $logout_url = common_local_url('logout');
  
      function reqFbScripts($action)
      {
+         if (!self::hasKeys()) {
+             return false;
+         }
  
          // If you're logged in w/FB Connect, you always need the FB stuff
  
  
      function onStartPrimaryNav($action)
      {
-         $user = common_current_user();
+         if (self::hasKeys()) {
+             $user = common_current_user();
+             if (!empty($user)) {
  
-         $connect = 'FBConnectSettings';
-         if (common_config('xmpp', 'enabled')) {
-             $connect = 'imsettings';
-         } else if (common_config('sms', 'enabled')) {
-             $connect = 'smssettings';
-         }
+                 $fbuid = $this->loggedIn();
  
-         if (!empty($user)) {
+                 if (!empty($fbuid)) {
  
-             $fbuid = $this->loggedIn();
+                     /* Default FB silhouette pic for FB users who haven't
+                        uploaded a profile pic yet. */
  
-             if (!empty($fbuid)) {
-                 /* Default FB silhouette pic for FB users who haven't
-                    uploaded a profile pic yet. */
-                 $silhouetteUrl =
-                     'http://static.ak.fbcdn.net/pics/q_silhouette.gif';
+                     $silhouetteUrl =
+                         'http://static.ak.fbcdn.net/pics/q_silhouette.gif';
  
-                 $url = $this->getProfilePicURL($fbuid);
+                     $url = $this->getProfilePicURL($fbuid);
  
-                 $action->elementStart('li', array('id' => 'nav_fb'));
+                     $action->elementStart('li', array('id' => 'nav_fb'));
  
-                 $action->element('img', array('id' => 'fbc_profile-pic',
-                     'src' => (!empty($url)) ? $url : $silhouetteUrl,
-                     'alt' => 'Facebook Connect User',
-                     'width' => '16'), '');
+                     $action->element('img', array('id' => 'fbc_profile-pic',
+                         'src' => (!empty($url)) ? $url : $silhouetteUrl,
+                         'alt' => 'Facebook Connect User',
+                         'width' => '16'), '');
  
-                 $iconurl =  common_path('plugins/Facebook/fbfavicon.ico');
-                 $action->element('img', array('id' => 'fb_favicon',
-                     'src' => $iconurl));
-                 $action->elementEnd('li');
+                     $iconurl =  common_path('plugins/Facebook/fbfavicon.ico');
+                     $action->element('img', array('id' => 'fb_favicon',
+                         'src' => $iconurl));
  
+                     $action->elementEnd('li');
+                 }
              }
          }
  
  
      function onEndLoginGroupNav(&$action)
      {
+         if (self::hasKeys()) {
  
-         $action_name = $action->trimmed('action');
-         $action->menuItem(common_local_url('FBConnectLogin'),
-                                            _m('Facebook'),
-                                            _m('Login or register using Facebook'),
-                                            'FBConnectLogin' === $action_name);
+             $action_name = $action->trimmed('action');
  
+             $action->menuItem(common_local_url('FBConnectLogin'),
+                                                _m('Facebook'),
+                                                _m('Login or register using Facebook'),
+                                                'FBConnectLogin' === $action_name);
+         }
          return true;
      }
  
  
      function onEndConnectSettingsNav(&$action)
      {
-         $action_name = $action->trimmed('action');
+         if (self::hasKeys()) {
  
-         $action->menuItem(common_local_url('FBConnectSettings'),
-                           _m('Facebook'),
-                           _m('Facebook Connect Settings'),
-                           $action_name === 'FBConnectSettings');
+             $action_name = $action->trimmed('action');
  
+             $action->menuItem(common_local_url('FBConnectSettings'),
+                               _m('Facebook'),
+                               _m('Facebook Connect Settings'),
+                               $action_name === 'FBConnectSettings');
+         }
          return true;
      }
  
  
      function onStartLogout($action)
      {
-         $action->logout();
-         $fbuid = $this->loggedIn();
+         if (self::hasKeys()) {
  
-         if (!empty($fbuid)) {
-             try {
-                 $facebook = getFacebook();
-                 $facebook->expire_session();
-             } catch (Exception $e) {
-                 common_log(LOG_WARNING, 'Facebook Connect Plugin - ' .
-                            'Could\'t logout of Facebook: ' .
-                            $e->getMessage());
+             $action->logout();
+             $fbuid = $this->loggedIn();
+             if (!empty($fbuid)) {
+                 try {
+                     $facebook = getFacebook();
+                     $facebook->expire_session();
+                 } catch (Exception $e) {
+                     common_log(LOG_WARNING, 'Facebook Connect Plugin - ' .
+                                'Could\'t logout of Facebook: ' .
+                                $e->getMessage());
+                 }
              }
          }
          return true;
      }
  
  
      function onStartEnqueueNotice($notice, &$transports)
      {
-         array_push($transports, 'facebook');
+         if (self::hasKeys()) {
+             array_push($transports, 'facebook');
+         }
          return true;
      }
  
       */
      function onEndInitializeQueueManager($manager)
      {
-         $manager->connect('facebook', 'FacebookQueueHandler');
+         if (self::hasKeys()) {
+             $manager->connect('facebook', 'FacebookQueueHandler');
+         }
          return true;
      }
  
index b69430ea78a74d890c90bc19ebfa38ea3fd8fa6e,ad4f613891206ce03cab76a72efc317cfd265c07..033325c9e5f33fe3a4855d8266c0fc4b0299e84b
@@@ -44,15 -44,19 +44,19 @@@ class OStatusPlugin extends Plugi
          $m->connect('.well-known/host-meta',
                      array('action' => 'hostmeta'));
          $m->connect('main/xrd',
-                     array('action' => 'xrd'));
+                     array('action' => 'userxrd'));
+         $m->connect('main/ownerxrd',
+                     array('action' => 'ownerxrd'));
          $m->connect('main/ostatus',
                      array('action' => 'ostatusinit'));
          $m->connect('main/ostatus?nickname=:nickname',
                    array('action' => 'ostatusinit'), array('nickname' => '[A-Za-z0-9_-]+'));
+         $m->connect('main/ostatus?group=:group',
+                   array('action' => 'ostatusinit'), array('group' => '[A-Za-z0-9_-]+'));
          $m->connect('main/ostatussub',
                      array('action' => 'ostatussub'));
-         $m->connect('main/ostatussub',
-                     array('action' => 'ostatussub'), array('feed' => '[A-Za-z0-9\.\/\:]+'));
+         $m->connect('main/ostatusgroup',
+                     array('action' => 'ostatusgroup'));
  
          // PuSH actions
          $m->connect('main/push/hub', array('action' => 'pushhub'));
      {
          if ($action instanceof ShowstreamAction) {
              $acct = 'acct:'. $action->profile->nickname .'@'. common_config('site', 'server');
-             $url = common_local_url('xrd');
+             $url = common_local_url('userxrd');
              $url.= '?uri='. $acct;
-             
              header('Link: <'.$url.'>; rel="'. Discovery::LRDD_REL.'"; type="application/xrd+xml"');
          }
      }
-     
      /**
       * Set up a PuSH hub link to our internal link for canonical timeline
       * Atom feeds for users and groups.
          return false;
      }
  
+     function onStartGroupSubscribe($output, $group)
+     {
+         $cur = common_current_user();
+         if (empty($cur)) {
+             // Add an OStatus subscribe
+             $url = common_local_url('ostatusinit',
+                                     array('group' => $group->nickname));
+             $output->element('a', array('href' => $url,
+                                         'class' => 'entity_remote_subscribe'),
+                                 _m('Join'));
+         }
+         return true;
+     }
      /**
       * Check if we've got remote replies to send via Salmon.
       *
  
      function onEndFindMentions($sender, $text, &$mentions)
      {
-         preg_match_all('!(?:^|\s+)
-                         @(                                # Webfinger:
-                           (?:\w+\.)*\w+                   #   user
-                           @                               #   @
-                           (?:\w+\.)*\w+(?:\w+\-\w+)*\.\w+ #   domain
-                          |                                # Profile:
-                           (?:\w+\.)*\w+(?:\w+\-\w+)*\.\w+ #   domain
-                           (?:/\w+)+                       #   /path1(/path2...)
-                          )!x',
+         $matches = array();
+         // Webfinger matches: @user@example.com
+         if (preg_match_all('!(?:^|\s+)@((?:\w+\.)*\w+@(?:\w+\.)*\w+(?:\w+\-\w+)*\.\w+)!',
                         $text,
                         $wmatches,
-                        PREG_OFFSET_CAPTURE);
-         foreach ($wmatches[1] as $wmatch) {
-             $target = $wmatch[0];
-             $oprofile = null;
-             if (strpos($target, '/') === false) {
-                 $this->log(LOG_INFO, "Checking Webfinger for address '$target'");
+                        PREG_OFFSET_CAPTURE)) {
+             foreach ($wmatches[1] as $wmatch) {
+                 list($target, $pos) = $wmatch;
+                 $this->log(LOG_INFO, "Checking webfinger '$target'");
                  try {
                      $oprofile = Ostatus_profile::ensureWebfinger($target);
+                     if ($oprofile && !$oprofile->isGroup()) {
+                         $profile = $oprofile->localProfile();
+                         $matches[$pos] = array('mentioned' => array($profile),
+                                                'text' => $target,
+                                                'position' => $pos,
+                                                'url' => $profile->profileurl);
+                     }
                  } catch (Exception $e) {
                      $this->log(LOG_ERR, "Webfinger check failed: " . $e->getMessage());
                  }
-             } else {
-                 $schemes = array('https', 'http');
+             }
+         }
+         // Profile matches: @example.com/mublog/user
+         if (preg_match_all('!(?:^|\s+)@((?:\w+\.)*\w+(?:\w+\-\w+)*\.\w+(?:/\w+)+)!',
+                        $text,
+                        $wmatches,
+                        PREG_OFFSET_CAPTURE)) {
+             foreach ($wmatches[1] as $wmatch) {
+                 list($target, $pos) = $wmatch;
+                 $schemes = array('http', 'https');
                  foreach ($schemes as $scheme) {
                      $url = "$scheme://$target";
                      $this->log(LOG_INFO, "Checking profile address '$url'");
                      try {
                          $oprofile = Ostatus_profile::ensureProfile($url);
-                         if ($oprofile) {
-                             continue;
+                         if ($oprofile && !$oprofile->isGroup()) {
+                             $profile = $oprofile->localProfile();
+                             $matches[$pos] = array('mentioned' => array($profile),
+                                                    'text' => $target,
+                                                    'position' => $pos,
+                                                    'url' => $profile->profileurl);
+                             break;
                          }
                      } catch (Exception $e) {
                          $this->log(LOG_ERR, "Profile check failed: " . $e->getMessage());
                      }
                  }
              }
+         }
  
-             if (empty($oprofile)) {
-                 $this->log(LOG_INFO, "No Ostatus_profile found for address '$target'");
-             } else {
-                 $this->log(LOG_INFO, "Ostatus_profile found for address '$target'");
-                 if ($oprofile->isGroup()) {
-                     continue;
-                 }
-                 $profile = $oprofile->localProfile();
-                 $pos = $wmatch[1];
-                 foreach ($mentions as $i => $other) {
-                     // If we share a common prefix with a local user, override it!
-                     if ($other['position'] == $pos) {
-                         unset($mentions[$i]);
-                     }
-                 }
-                 $mentions[] = array('mentioned' => array($profile),
-                                     'text' => $target,
-                                     'position' => $pos,
-                                     'url' => $profile->profileurl);
+         foreach ($mentions as $i => $other) {
+             // If we share a common prefix with a local user, override it!
+             $pos = $other['position'];
+             if (isset($matches[$pos])) {
+                 $mentions[$i] = $matches[$pos];
+                 unset($matches[$pos]);
              }
          }
+         foreach ($matches as $mention) {
+             $mentions[] = $mention;
+         }
  
          return true;
      }
      }
  
      function onEndShowStatusNetStyles($action) {
 -        $action->cssLink(common_path('plugins/OStatus/theme/base/css/ostatus.css'));
 +        $action->cssLink('plugins/OStatus/theme/base/css/ostatus.css');
          return true;
      }
  
      function onEndShowStatusNetScripts($action) {
 -        $action->script(common_path('plugins/OStatus/js/ostatus.js'));
 +        $action->script('plugins/OStatus/js/ostatus.js');
          return true;
      }
  
              // Drop the PuSH subscription if there are no other subscribers.
              $oprofile->garbageCollect();
  
              $member = Profile::staticGet($user->id);
  
              $act = new Activity();
          return true;
      }
  
-     function onStartShowAllContent($action)
+     function onStartShowUserGroupsContent($action)
+     {
+         $this->showEntityRemoteSubscribe($action, 'ostatusgroup');
+         return true;
+     }
+     function onEndShowSubscriptionsMiniList($action)
      {
          $this->showEntityRemoteSubscribe($action);
  
          return true;
      }
  
-     function showEntityRemoteSubscribe($action)
+     function onEndShowGroupsMiniList($action)
+     {
+         $this->showEntityRemoteSubscribe($action, 'ostatusgroup');
+         return true;
+     }
+     function showEntityRemoteSubscribe($action, $target='ostatussub')
      {
          $user = common_current_user();
          if ($user && ($user->id == $action->profile->id)) {
              $action->elementStart('div', 'entity_actions');
              $action->elementStart('p', array('id' => 'entity_remote_subscribe',
                                               'class' => 'entity_subscribe'));
-             $action->element('a', array('href' => common_local_url('ostatussub'),
+             $action->element('a', array('href' => common_local_url($target),
                                          'class' => 'entity_remote_subscribe')
-                                 , _m('Subscribe to remote user'));
+                                 , _m('Remote'));
              $action->elementEnd('p');
              $action->elementEnd('div');
          }
  
          return true;
      }
+     function onStartProfileListItemActionElements($item)
+     {
+         if (!common_logged_in()) {
+             $profileUser = User::staticGet('id', $item->profile->id);
+             if (!empty($profileUser)) {
+                 $output = $item->out;
+                 // Add an OStatus subscribe
+                 $output->elementStart('li', 'entity_subscribe');
+                 $url = common_local_url('ostatusinit',
+                                         array('nickname' => $profileUser->nickname));
+                 $output->element('a', array('href' => $url,
+                                             'class' => 'entity_remote_subscribe'),
+                                  _m('Subscribe'));
+                 $output->elementEnd('li');
+             }
+         }
+         return true;
+     }
  }