]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch '0.9.x' into 1.0.x
authorCraig Andrews <candrews@integralblue.com>
Sun, 18 Apr 2010 23:21:15 +0000 (19:21 -0400)
committerCraig Andrews <candrews@integralblue.com>
Sun, 18 Apr 2010 23:21:15 +0000 (19:21 -0400)
Conflicts:
actions/confirmaddress.php
actions/imsettings.php

1  2 
actions/apiaccountupdatedeliverydevice.php
actions/confirmaddress.php
actions/imsettings.php
actions/shownotice.php
classes/User.php
lib/adminpanelaction.php
lib/command.php
lib/implugin.php
lib/statusnet.php
lib/util.php

index eaf1c91c1a5c897053583c455b8e38affcc4908b,8bf8c8c4d4d7a75de8c27ba5029421d88b3c0aac..f92db3ec452b3deccc72321352553387da80d466
@@@ -86,75 -86,39 +86,76 @@@ class ConfirmaddressAction extends Acti
              return;
          }
          $type = $confirm->address_type;
 -        if (!in_array($type, array('email', 'jabber', 'sms'))) {
 -            // TRANS: Server error for an unknow address type, which can be 'email', 'jabber', or 'sms'.
 -            $this->serverError(sprintf(_('Unrecognized address type %s.'), $type));
 +        $transports = array();
 +        Event::handle('GetImTransports', array(&$transports));
 +        if (!in_array($type, array('email', 'sms')) && !in_array($type, array_keys($transports))) {
++            // TRANS: Server error for an unknown address type, which can be 'email', 'sms', or the name of an IM network (such as 'xmpp' or 'aim')
 +            $this->serverError(sprintf(_('Unrecognized address type %s'), $type));
              return;
          }
 -        if ($cur->$type == $confirm->address) {
 -            // TRANS: Client error for an already confirmed email/jabbel/sms address.
 -            $this->clientError(_('That address has already been confirmed.'));
 -            return;
 -        }
 -
 +        $this->address = $confirm->address;
          $cur->query('BEGIN');
 +        if (in_array($type, array('email', 'sms')))
 +        {
 +            if ($cur->$type == $confirm->address) {
 +                $this->clientError(_('That address has already been confirmed.'));
 +                return;
 +            }
 +
 +            $orig_user = clone($cur);
 +
 +            $cur->$type = $confirm->address;
 +
 +            if ($type == 'sms') {
 +                $cur->carrier  = ($confirm->address_extra)+0;
 +                $carrier       = Sms_carrier::staticGet($cur->carrier);
 +                $cur->smsemail = $carrier->toEmailAddress($cur->sms);
 +            }
 +
 +            $result = $cur->updateKeys($orig_user);
 +
 +            if (!$result) {
 +                common_log_db_error($cur, 'UPDATE', __FILE__);
 +                $this->serverError(_('Couldn\'t update user.'));
 +                return;
 +            }
 +
 +            if ($type == 'email') {
 +                $cur->emailChanged();
 +            }
 +
 +        } else {
 +
 +            $user_im_prefs = new User_im_prefs();
 +            $user_im_prefs->transport = $confirm->address_type;
 +            $user_im_prefs->user_id = $cur->id;
 +            if ($user_im_prefs->find() && $user_im_prefs->fetch()) {
 +                if($user_im_prefs->screenname == $confirm->address){
 +                    $this->clientError(_('That address has already been confirmed.'));
 +                    return;
 +                }
 +                $user_im_prefs->screenname = $confirm->address;
 +                $result = $user_im_prefs->update();
 +
 +                if (!$result) {
 +                    common_log_db_error($user_im_prefs, 'UPDATE', __FILE__);
 +                    $this->serverError(_('Couldn\'t update user im preferences.'));
 +                    return;
 +                }
 +            }else{
 +                $user_im_prefs = new User_im_prefs();
 +                $user_im_prefs->screenname = $confirm->address;
 +                $user_im_prefs->transport = $confirm->address_type;
 +                $user_im_prefs->user_id = $cur->id;
 +                $result = $user_im_prefs->insert();
 +
 +                if (!$result) {
 +                    common_log_db_error($user_im_prefs, 'INSERT', __FILE__);
 +                    $this->serverError(_('Couldn\'t insert user im preferences.'));
 +                    return;
 +                }
 +            }
  
 -        $orig_user = clone($cur);
 -
 -        $cur->$type = $confirm->address;
 -
 -        if ($type == 'sms') {
 -            $cur->carrier  = ($confirm->address_extra)+0;
 -            $carrier       = Sms_carrier::staticGet($cur->carrier);
 -            $cur->smsemail = $carrier->toEmailAddress($cur->sms);
 -        }
 -
 -        $result = $cur->updateKeys($orig_user);
 -
 -        if (!$result) {
 -            common_log_db_error($cur, 'UPDATE', __FILE__);
 -            $this->serverError(_('Couldn\'t update user.'));
 -            return;
 -        }
 -
 -        if ($type == 'email') {
 -            $cur->emailChanged();
          }
  
          $result = $confirm->delete();
index fe1864f0d1cb6c326af4762cc57ff2c0b84c1190,6691c8dad76e95f53cbcf621810a3490ea813f95..2c2606b76c78765a93f69c74ff8a7ef96b37d5f1
@@@ -64,9 -68,12 +65,12 @@@ class ImsettingsAction extends ConnectS
  
      function getInstructions()
      {
+         // TRANS: Instant messaging settings page instructions.
+         // TRANS: [instant messages] is link text, "(%%doc.im%%)" is the link.
+         // TRANS: the order and formatting of link text and link should remain unchanged.
          return _('You can send and receive notices through '.
 -                 'Jabber/GTalk [instant messages](%%doc.im%%). '.
 -                 'Configure your address and settings below.');
 +                 'instant messaging [instant messages](%%doc.im%%). '.
 +                 'Configure your addresses and settings below.');
      }
  
      /**
  
      function showContent()
      {
 -        if (!common_config('xmpp', 'enabled')) {
 +        $transports = array();
 +        Event::handle('GetImTransports', array(&$transports));
 +        if (! $transports) {
              $this->element('div', array('class' => 'error'),
 -                           // TRANS: Message given in the IM settings if XMPP is not enabled on the site.
++                           // TRANS: Message given in the IM settings if IM is not enabled on the site.
                             _('IM is not available.'));
              return;
          }
  
          $user = common_current_user();
 -        $this->elementStart('form', array('method' => 'post',
 -                                          'id' => 'form_settings_im',
 -                                          'class' => 'form_settings',
 -                                          'action' =>
 -                                          common_local_url('imsettings')));
 -        $this->elementStart('fieldset', array('id' => 'settings_im_address'));
 -        // TRANS: Form legend for IM settings form.
 -        $this->element('legend', null, _('IM address'));
 -        $this->hidden('token', common_session_token());
 -
 -        if ($user->jabber) {
 -            $this->element('p', 'form_confirmed', $user->jabber);
 -            // TRANS: Form note in IM settings form.
 -            $this->element('p', 'form_note',
 -                           _('Current confirmed Jabber/GTalk address.'));
 -            $this->hidden('jabber', $user->jabber);
 -            // TRANS: Button label to remove a confirmed IM address.
 -            $this->submit('remove', _m('BUTTON','Remove'));
 -        } else {
 -            $confirm = $this->getConfirmation();
 -            if ($confirm) {
 -                $this->element('p', 'form_unconfirmed', $confirm->address);
 +
 +        $user_im_prefs_by_transport = array();
 +        
 +        foreach($transports as $transport=>$transport_info)
 +        {
 +            $this->elementStart('form', array('method' => 'post',
 +                                              'id' => 'form_settings_im',
 +                                              'class' => 'form_settings',
 +                                              'action' =>
 +                                              common_local_url('imsettings')));
 +            $this->elementStart('fieldset', array('id' => 'settings_im_address'));
++            // TRANS: Form legend for IM settings form.
 +            $this->element('legend', null, $transport_info['display']);
 +            $this->hidden('token', common_session_token());
 +            $this->hidden('transport', $transport);
 +
 +            if ($user_im_prefs = User_im_prefs::pkeyGet( array('transport' => $transport, 'user_id' => $user->id) )) {
 +                $user_im_prefs_by_transport[$transport] = $user_im_prefs;
 +                $this->element('p', 'form_confirmed', $user_im_prefs->screenname);
++                // TRANS: Form note in IM settings form.
                  $this->element('p', 'form_note',
 -                               // TRANS: Form note in IM settings form.
 -                               // TRANS: %s is the IM address set for the site.
 -                               sprintf(_('Awaiting confirmation on this address. '.
 -                                         'Check your Jabber/GTalk account for a '.
 -                                         'message with further instructions. '.
 -                                         '(Did you add %s to your buddy list?)'),
 -                                       jabber_daemon_address()));
 -                $this->hidden('jabber', $confirm->address);
 -                // TRANS: Button label to cancel an IM address confirmation procedure.
 -                $this->submit('cancel', _m('BUTTON','Cancel'));
 +                               sprintf(_('Current confirmed %s address.'),$transport_info['display']));
 +                $this->hidden('screenname', $user_im_prefs->screenname);
-                 $this->submit('remove', _('Remove'));
++                // TRANS: Button label to remove a confirmed IM address.
++                $this->submit('remove', _m('BUTTON','Remove'));
              } else {
 -                $this->elementStart('ul', 'form_data');
 -                $this->elementStart('li');
 -                // TRANS: Field label for IM address input in IM settings form.
 -                $this->input('jabber', _('IM address'),
 -                             ($this->arg('jabber')) ? $this->arg('jabber') : null,
 -                             // TRANS: IM address input field instructions in IM settings form.
 -                             // TRANS: %s is the IM address set for the site.
 -                             sprintf(_('Jabber or GTalk address, '.
 -                                       'like "UserName@example.org". '.
 -                                       'First, make sure to add %s to your '.
 -                                       'buddy list in your IM client or on GTalk.'),
 -                                     jabber_daemon_address()));
 -                $this->elementEnd('li');
 -                $this->elementEnd('ul');
 -                // TRANS: Button label for adding an IM address in IM settings form.
 -                $this->submit('add', _m('BUTTON','Add'));
 +                $confirm = $this->getConfirmation($transport);
 +                if ($confirm) {
 +                    $this->element('p', 'form_unconfirmed', $confirm->address);
++                    // TRANS: Form note in IM settings form.
 +                    $this->element('p', 'form_note',
++                                   // TRANS: Form note in IM settings form.
++                                   // TRANS: %s is the IM address set for the site.
 +                                   sprintf(_('Awaiting confirmation on this address. '.
 +                                             'Check your %s account for a '.
-                                              'message with further instructions.'),
-                                            $transport_info['display']));
++                                             'message with further instructions. '.
++                                             '(Did you add %s to your buddy list?)'),
++                                             $transport_info['display'],
++                                             $transport_info['daemon_screenname'],
++                                             jabber_daemon_address()));
 +                    $this->hidden('screenname', $confirm->address);
-                     $this->submit('cancel', _('Cancel'));
++                    // TRANS: Button label to cancel an IM address confirmation procedure.
++                    $this->submit('cancel', _m('BUTTON','Cancel'));
 +                } else {
 +                    $this->elementStart('ul', 'form_data');
 +                    $this->elementStart('li');
 +                    $this->input('screenname', _('IM address'),
 +                                 ($this->arg('screenname')) ? $this->arg('screenname') : null,
 +                                 sprintf(_('%s screenname.'),
 +                                         $transport_info['display']));
 +                    $this->elementEnd('li');
 +                    $this->elementEnd('ul');
-                     $this->submit('add', _('Add'));
++                    // TRANS: Button label for adding an IM address in IM settings form.
++                    $this->submit('add', _m('BUTTON','Add'));
 +                }
              }
-             $this->element('th', null, _('Preferences'));
 +            $this->elementEnd('fieldset');
 +            $this->elementEnd('form');
 +        }
 +
 +        if($user_im_prefs_by_transport)
 +        {
 +            $this->elementStart('form', array('method' => 'post',
 +                                              'id' => 'form_settings_im',
 +                                              'class' => 'form_settings',
 +                                              'action' =>
 +                                              common_local_url('imsettings')));
 +            $this->elementStart('fieldset', array('id' => 'settings_im_preferences'));
 +            $this->element('legend', null, _('Preferences'));
 +            $this->hidden('token', common_session_token());
 +            $this->elementStart('table');
 +            $this->elementStart('tr');
-             $this->submit('save', _('Save'));
++            // TRANS: Header for IM preferences form.
++            $this->element('th', null, _('IM Preferences'));
 +            foreach($user_im_prefs_by_transport as $transport=>$user_im_prefs)
 +            {
 +                $this->element('th', null, $transports[$transport]['display']);
 +            }
 +            $this->elementEnd('tr');
 +            $preferences = array(
++                // TRANS: Checkbox label in IM preferences form.
 +                array('name'=>'notify', 'description'=>_('Send me notices')),
++                // TRANS: Checkbox label in IM preferences form.
 +                array('name'=>'updatefrompresence', 'description'=>_('Post a notice when my status changes.')),
++                // TRANS: Checkbox label in IM preferences form.
 +                array('name'=>'replies', 'description'=>_('Send me replies '.
 +                              'from people I\'m not subscribed to.')),
++                // TRANS: Checkbox label in IM preferences form.
 +                array('name'=>'microid', 'description'=>_('Publish a MicroID'))
 +            );
 +            foreach($preferences as $preference)
 +            {
 +                $this->elementStart('tr');
 +                foreach($user_im_prefs_by_transport as $transport=>$user_im_prefs)
 +                {
 +                    $preference_name = $preference['name'];
 +                    $this->elementStart('td');
 +                    $this->checkbox($transport . '_' . $preference['name'],
 +                                $preference['description'],
 +                                $user_im_prefs->$preference_name);
 +                    $this->elementEnd('td');
 +                }
 +                $this->elementEnd('tr');
 +            }
 +            $this->elementEnd('table');
++            // TRANS: Button label to save IM preferences.
++            $this->submit('save', _m('BUTTON','Save'));
 +            $this->elementEnd('fieldset');
 +            $this->elementEnd('form');
          }
 -        $this->elementEnd('fieldset');
 -        
 -        $this->elementStart('fieldset', array('id' => 'settings_im_preferences'));
 -        // TRANS: Form legend for IM preferences form.
 -        $this->element('legend', null, _('IM preferences'));
 -        $this->elementStart('ul', 'form_data');
 -        $this->elementStart('li');
 -        $this->checkbox('jabbernotify',
 -                        // TRANS: Checkbox label in IM preferences form.
 -                        _('Send me notices through Jabber/GTalk.'),
 -                        $user->jabbernotify);
 -        $this->elementEnd('li');
 -        $this->elementStart('li');
 -        $this->checkbox('updatefrompresence',
 -                        // TRANS: Checkbox label in IM preferences form.
 -                        _('Post a notice when my Jabber/GTalk status changes.'),
 -                        $user->updatefrompresence);
 -        $this->elementEnd('li');
 -        $this->elementStart('li');
 -        $this->checkbox('jabberreplies',
 -                        // TRANS: Checkbox label in IM preferences form.
 -                        _('Send me replies through Jabber/GTalk '.
 -                          'from people I\'m not subscribed to.'),
 -                        $user->jabberreplies);
 -        $this->elementEnd('li');
 -        $this->elementStart('li');
 -        $this->checkbox('jabbermicroid',
 -                        // TRANS: Checkbox label in IM preferences form.
 -                        _('Publish a MicroID for my Jabber/GTalk address.'),
 -                        $user->jabbermicroid);
 -        $this->elementEnd('li');
 -        $this->elementEnd('ul');
 -        // TRANS: Button label to save IM preferences.
 -        $this->submit('save', _m('BUTTON','Save'));
 -        $this->elementEnd('fieldset');
 -        $this->elementEnd('form');
      }
  
      /**
  
      function savePreferences()
      {
 -        $jabbernotify       = $this->boolean('jabbernotify');
 -        $updatefrompresence = $this->boolean('updatefrompresence');
 -        $jabberreplies      = $this->boolean('jabberreplies');
 -        $jabbermicroid      = $this->boolean('jabbermicroid');
 -
          $user = common_current_user();
  
 -        assert(!is_null($user)); // should already be checked
 -
 -        $user->query('BEGIN');
 -
 -        $original = clone($user);
 -
 -        $user->jabbernotify       = $jabbernotify;
 -        $user->updatefrompresence = $updatefrompresence;
 -        $user->jabberreplies      = $jabberreplies;
 -        $user->jabbermicroid      = $jabbermicroid;
 -
 -        $result = $user->update($original);
 -
 -        if ($result === false) {
 -            common_log_db_error($user, 'UPDATE', __FILE__);
 -            // TRANS: Server error thrown on database error updating IM preferences.
 -            $this->serverError(_('Couldn\'t update user.'));
 -            return;
 +        $user_im_prefs = new User_im_prefs();
 +        $user_im_prefs->user_id = $user->id;
 +        if($user_im_prefs->find() && $user_im_prefs->fetch())
 +        {
 +            $preferences = array('notify', 'updatefrompresence', 'replies', 'microid');
 +            $user_im_prefs->query('BEGIN');
 +            do
 +            {
 +                $original = clone($user_im_prefs);
 +                foreach($preferences as $preference)
 +                {
 +                    $user_im_prefs->$preference = $this->boolean($user_im_prefs->transport . '_' . $preference);
 +                }
 +                $result = $user_im_prefs->update($original);
 +
 +                if ($result === false) {
 +                    common_log_db_error($user, 'UPDATE', __FILE__);
++                    // TRANS: Server error thrown on database error updating IM preferences.
 +                    $this->serverError(_('Couldn\'t update IM preferences.'));
 +                    return;
 +                }
 +            }while($user_im_prefs->fetch());
 +            $user_im_prefs->query('COMMIT');
          }
 -
 -        $user->query('COMMIT');
 -
+         // TRANS: Confirmation message for successful IM preferences save.
          $this->showForm(_('Preferences saved.'), true);
      }
  
  
          // Some validation
  
 -        if (!$jabber) {
 +        if (!$screenname) {
+             // TRANS: Message given saving IM address without having provided one.
 -            $this->showForm(_('No Jabber ID.'));
 +            $this->showForm(_('No screenname.'));
              return;
          }
  
 -        $jabber = jabber_normalize_jid($jabber);
 +        if (!$transport) {
 +            $this->showForm(_('No transport.'));
 +            return;
 +        }
  
 -        if (!$jabber) {
 +        Event::handle('NormalizeImScreenname', array($transport, &$screenname));
 +
 +        if (!$screenname) {
+             // TRANS: Message given saving IM address that cannot be normalised.
 -            $this->showForm(_('Cannot normalize that Jabber ID'));
 +            $this->showForm(_('Cannot normalize that screenname'));
              return;
          }
 -        if (!jabber_valid_base_jid($jabber, common_config('email', 'domain_check'))) {
 +        $valid = false;
 +        Event::handle('ValidateImScreenname', array($transport, $screenname, &$valid));
 +        if (!$valid) {
+             // TRANS: Message given saving IM address that not valid.
 -            $this->showForm(_('Not a valid Jabber ID'));
 -            return;
 -        } else if ($user->jabber == $jabber) {
 -            // TRANS: Message given saving IM address that is already set.
 -            $this->showForm(_('That is already your Jabber ID.'));
 +            $this->showForm(_('Not a valid screenname'));
              return;
 -        } else if ($this->jabberExists($jabber)) {
 +        } else if ($this->screennameExists($transport, $screenname)) {
+             // TRANS: Message given saving IM address that is already set for another user.
 -            $this->showForm(_('Jabber ID already belongs to another user.'));
 +            $this->showForm(_('Screenname already belongs to another user.'));
              return;
          }
  
              return;
          }
  
 -        jabber_confirm_address($confirm->code,
 -                               $user->nickname,
 -                               $jabber);
 +        Event::handle('SendImConfirmationCode', array($transport, $screenname, $confirm->code, $user));
  
 -        // TRANS: %s is the IM address set for the site.
 -        $msg = sprintf(_('A confirmation code was sent '.
 -                         'to the IM address you added. '.
 -                         'You must approve %s for '.
 -                         'sending messages to you.'),
 -                       jabber_daemon_address());
+         // TRANS: Message given saving valid IM address that is to be confirmed.
 +        $msg = _('A confirmation code was sent '.
 +                         'to the IM address you added.');
  
          $this->showForm($msg, true);
      }
  
      function cancelConfirmation()
      {
 -        $jabber = $this->arg('jabber');
 +        $screenname = $this->trimmed('screenname');
 +        $transport = $this->trimmed('transport');
  
 -        $confirm = $this->getConfirmation();
 +        $confirm = $this->getConfirmation($transport);
  
          if (!$confirm) {
+             // TRANS: Message given canceling IM address confirmation that is not pending.
              $this->showForm(_('No pending confirmation to cancel.'));
              return;
          }
 -        if ($confirm->address != $jabber) {
 +        if ($confirm->address != $screenname) {
+             // TRANS: Message given canceling IM address confirmation for the wrong IM address.
              $this->showForm(_('That is the wrong IM address.'));
              return;
          }
  
          if (!$result) {
              common_log_db_error($confirm, 'DELETE', __FILE__);
 -            $this->serverError(_('Couldn\'t delete IM confirmation.'));
+             // TRANS: Server error thrown on database error canceling IM address confirmation.
 +            $this->serverError(_('Couldn\'t delete confirmation.'));
              return;
          }
  
  
          // Maybe an old tab open...?
  
 -        if ($user->jabber != $jabber) {
 +        $user_im_prefs = new User_im_prefs();
 +        $user_im_prefs->user_id = $user->id;
 +        if(! ($user_im_prefs->find() && $user_im_prefs->fetch())) {
+             // TRANS: Message given trying to remove an IM address that is not
+             // TRANS: registered for the active user.
 -            $this->showForm(_('That is not your Jabber ID.'));
 +            $this->showForm(_('That is not your screenname.'));
              return;
          }
  
  
          if (!$result) {
              common_log_db_error($user, 'UPDATE', __FILE__);
+             // TRANS: Server error thrown on database error removing a registered IM address.
 +            $this->serverError(_('Couldn\'t update user im prefs.'));
+             $this->serverError(_('Couldn\'t update user.'));
              return;
          }
 -        $user->query('COMMIT');
  
          // XXX: unsubscribe to the old address
  
Simple merge
Simple merge
Simple merge
diff --cc lib/command.php
Simple merge
index 018b0ecee08e51c7b9c7c57571d8249dac2d91d4,0000000000000000000000000000000000000000..7302859a47d73d728d0e1045ec7b0df9621d84ef
mode 100644,000000..100644
--- /dev/null
@@@ -1,613 -1,0 +1,615 @@@
-         $transports[$this->transport] = array('display' => $this->getDisplayName());
 +<?php
 +/**
 + * StatusNet, the distributed open-source microblogging tool
 + *
 + * Superclass for plugins that do instant messaging
 + *
 + * PHP version 5
 + *
 + * LICENCE: This program is free software: you can redistribute it and/or modify
 + * it under the terms of the GNU Affero General Public License as published by
 + * the Free Software Foundation, either version 3 of the License, or
 + * (at your option) any later version.
 + *
 + * This program is distributed in the hope that it will be useful,
 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 + * GNU Affero General Public License for more details.
 + *
 + * You should have received a copy of the GNU Affero General Public License
 + * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 + *
 + * @category  Plugin
 + * @package   StatusNet
 + * @author    Craig Andrews <candrews@integralblue.com>
 + * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 + * @link      http://status.net/
 + */
 +
 +if (!defined('STATUSNET') && !defined('LACONICA')) {
 +    exit(1);
 +}
 +
 +/**
 + * Superclass for plugins that do authentication
 + *
 + * Implementations will likely want to override onStartIoManagerClasses() so that their
 + *   IO manager is used
 + *
 + * @category Plugin
 + * @package  StatusNet
 + * @author   Craig Andrews <candrews@integralblue.com>
 + * @license  http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
 + * @link     http://status.net/
 + */
 +
 +abstract class ImPlugin extends Plugin
 +{
 +    //name of this IM transport
 +    public $transport = null;
 +    //list of screennames that should get all public notices
 +    public $public = array();
 +
 +    /**
 +     * normalize a screenname for comparison
 +     *
 +     * @param string $screenname screenname to normalize
 +     *
 +     * @return string an equivalent screenname in normalized form
 +     */
 +    abstract function normalize($screenname);
 +
 +
 +    /**
 +     * validate (ensure the validity of) a screenname
 +     *
 +     * @param string $screenname screenname to validate
 +     *
 +     * @return boolean
 +     */
 +    abstract function validate($screenname);
 +
 +    /**
 +     * get the internationalized/translated display name of this IM service
 +     *
 +     * @return string
 +     */
 +    abstract function getDisplayName();
 +
 +    /**
 +     * send a single notice to a given screenname
 +     * The implementation should put raw data, ready to send, into the outgoing
 +     *   queue using enqueue_outgoing_raw()
 +     *
 +     * @param string $screenname screenname to send to
 +     * @param Notice $notice notice to send
 +     *
 +     * @return boolean success value
 +     */
 +    function send_notice($screenname, $notice)
 +    {
 +        return $this->send_message($screenname, $this->format_notice($notice));
 +    }
 +
 +    /**
 +     * send a message (text) to a given screenname
 +     * The implementation should put raw data, ready to send, into the outgoing
 +     *   queue using enqueue_outgoing_raw()
 +     *
 +     * @param string $screenname screenname to send to
 +     * @param Notice $body text to send
 +     *
 +     * @return boolean success value
 +     */
 +    abstract function send_message($screenname, $body);
 +
 +    /**
 +     * receive a raw message
 +     * Raw IM data is taken from the incoming queue, and passed to this function.
 +     * It should parse the raw message and call handle_incoming()
 +     *
 +     * @param object $data raw IM data
 +     *
 +     * @return boolean success value
 +     */
 +    abstract function receive_raw_message($data);
 +
 +    /**
 +     * get the screenname of the daemon that sends and receives message for this service
 +     *
 +     * @return string screenname of this plugin
 +     */
 +    abstract function daemon_screenname();
 +
 +    /**
 +     * get the microid uri of a given screenname
 +     *
 +     * @param string $screenname screenname
 +     *
 +     * @return string microid uri
 +     */
 +    function microiduri($screenname)
 +    {
 +        return $this->transport . ':' . $screenname;    
 +    }
 +    //========================UTILITY FUNCTIONS USEFUL TO IMPLEMENTATIONS - MISC ========================\
 +
 +    /**
 +     * Put raw message data (ready to send) into the outgoing queue
 +     *
 +     * @param object $data
 +     */
 +    function enqueue_outgoing_raw($data)
 +    {
 +        $qm = QueueManager::get();
 +        $qm->enqueue($data, $this->transport . '-out');
 +    }
 +
 +    /**
 +     * Put raw message data (received, ready to be processed) into the incoming queue
 +     *
 +     * @param object $data
 +     */
 +    function enqueue_incoming_raw($data)
 +    {
 +        $qm = QueueManager::get();
 +        $qm->enqueue($data, $this->transport . '-in');
 +    }
 +
 +    /**
 +     * given a screenname, get the corresponding user
 +     *
 +     * @param string $screenname
 +     *
 +     * @return User user
 +     */
 +    function get_user($screenname)
 +    {
 +        $user_im_prefs = $this->get_user_im_prefs_from_screenname($screenname);
 +        if($user_im_prefs){
 +            $user = User::staticGet('id', $user_im_prefs->user_id);
 +            $user_im_prefs->free();
 +            return $user;
 +        }else{
 +            return false;
 +        }
 +    }
 +
 +
 +    /**
 +     * given a screenname, get the User_im_prefs object for this transport
 +     *
 +     * @param string $screenname
 +     *
 +     * @return User_im_prefs user_im_prefs
 +     */
 +    function get_user_im_prefs_from_screenname($screenname)
 +    {
 +        if($user_im_prefs = User_im_prefs::pkeyGet( array('transport' => $this->transport, 'screenname' => $screenname) )){
 +            return $user_im_prefs;
 +        }else{
 +            return false;
 +        }
 +    }
 +
 +
 +    /**
 +     * given a User, get their screenname
 +     *
 +     * @param User $user
 +     *
 +     * @return string screenname of that user
 +     */
 +    function get_screenname($user)
 +    {
 +        $user_im_prefs = $this->get_user_im_prefs_from_user($user);
 +        if($user_im_prefs){
 +            return $user_im_prefs->screenname;
 +        }else{
 +            return false;
 +        }
 +    }
 +
 +
 +    /**
 +     * given a User, get their User_im_prefs
 +     *
 +     * @param User $user
 +     *
 +     * @return User_im_prefs user_im_prefs of that user
 +     */
 +    function get_user_im_prefs_from_user($user)
 +    {
 +        if($user_im_prefs = User_im_prefs::pkeyGet( array('transport' => $this->transport, 'user_id' => $user->id) )){
 +            return $user_im_prefs;
 +        }else{
 +            return false;
 +        }
 +    }
 +    //========================UTILITY FUNCTIONS USEFUL TO IMPLEMENTATIONS - SENDING ========================\
 +    /**
 +     * Send a message to a given screenname from the site
 +     *
 +     * @param string $screenname screenname to send the message to
 +     * @param string $msg message contents to send
 +     *
 +     * @param boolean success
 +     */
 +    protected function send_from_site($screenname, $msg)
 +    {
 +        $text = '['.common_config('site', 'name') . '] ' . $msg;
 +        $this->send_message($screenname, $text);
 +    }
 +
 +    /**
 +     * send a confirmation code to a user
 +     *
 +     * @param string $screenname screenname sending to
 +     * @param string $code the confirmation code
 +     * @param User $user user sending to
 +     *
 +     * @return boolean success value
 +     */
 +    function send_confirmation_code($screenname, $code, $user)
 +    {
 +        $body = sprintf(_('User "%s" on %s has said that your %s screenname belongs to them. ' .
 +          'If that\'s true, you can confirm by clicking on this URL: ' .
 +          '%s' .
 +          ' . (If you cannot click it, copy-and-paste it into the ' .
 +          'address bar of your browser). If that user isn\'t you, ' .
 +          'or if you didn\'t request this confirmation, just ignore this message.'),
 +          $user->nickname, common_config('site', 'name'), $this->getDisplayName(), common_local_url('confirmaddress', array('code' => $code)));
 +
 +        return $this->send_message($screenname, $body);
 +    }
 +
 +    /**
 +     * send a notice to all public listeners
 +     *
 +     * For notices that are generated on the local system (by users), we can optionally
 +     * forward them to remote listeners by XMPP.
 +     *
 +     * @param Notice $notice notice to broadcast
 +     *
 +     * @return boolean success flag
 +     */
 +
 +    function public_notice($notice)
 +    {
 +        // Now, users who want everything
 +
 +        // FIXME PRIV don't send out private messages here
 +        // XXX: should we send out non-local messages if public,localonly
 +        // = false? I think not
 +
 +        foreach ($this->public as $screenname) {
 +            common_log(LOG_INFO,
 +                       'Sending notice ' . $notice->id .
 +                       ' to public listener ' . $screenname,
 +                       __FILE__);
 +            $this->send_notice($screenname, $notice);
 +        }
 +
 +        return true;
 +    }
 +
 +    /**
 +     * broadcast a notice to all subscribers and reply recipients
 +     *
 +     * This function will send a notice to all subscribers on the local server
 +     * who have IM addresses, and have IM notification enabled, and
 +     * have this subscription enabled for IM. It also sends the notice to
 +     * all recipients of @-replies who have IM addresses and IM notification
 +     * enabled. This is really the heart of IM distribution in StatusNet.
 +     *
 +     * @param Notice $notice The notice to broadcast
 +     *
 +     * @return boolean success flag
 +     */
 +
 +    function broadcast_notice($notice)
 +    {
 +
 +        $ni = $notice->whoGets();
 +
 +        foreach ($ni as $user_id => $reason) {
 +            $user = User::staticGet($user_id);
 +            if (empty($user)) {
 +                // either not a local user, or just not found
 +                continue;
 +            }
 +            $user_im_prefs = $this->get_user_im_prefs_from_user($user);
 +            if(!$user_im_prefs || !$user_im_prefs->notify){
 +                continue;
 +            }
 +
 +            switch ($reason) {
 +            case NOTICE_INBOX_SOURCE_REPLY:
 +                if (!$user_im_prefs->replies) {
 +                    continue 2;
 +                }
 +                break;
 +            case NOTICE_INBOX_SOURCE_SUB:
 +                $sub = Subscription::pkeyGet(array('subscriber' => $user->id,
 +                                                   'subscribed' => $notice->profile_id));
 +                if (empty($sub) || !$sub->jabber) {
 +                    continue 2;
 +                }
 +                break;
 +            case NOTICE_INBOX_SOURCE_GROUP:
 +                break;
 +            default:
 +                throw new Exception(sprintf(_("Unknown inbox source %d."), $reason));
 +            }
 +
 +            common_log(LOG_INFO,
 +                       'Sending notice ' . $notice->id . ' to ' . $user_im_prefs->screenname,
 +                       __FILE__);
 +            $this->send_notice($user_im_prefs->screenname, $notice);
 +            $user_im_prefs->free();
 +        }
 +
 +        return true;
 +    }
 +
 +    /**
 +     * makes a plain-text formatted version of a notice, suitable for IM distribution
 +     *
 +     * @param Notice  $notice  notice being sent
 +     *
 +     * @return string plain-text version of the notice, with user nickname prefixed
 +     */
 +
 +    function format_notice($notice)
 +    {
 +        $profile = $notice->getProfile();
 +        return $profile->nickname . ': ' . $notice->content . ' [' . $notice->id . ']';
 +    }
 +    //========================UTILITY FUNCTIONS USEFUL TO IMPLEMENTATIONS - RECEIVING ========================\
 +
 +    /**
 +     * Attempt to handle a message as a command
 +     * @param User $user user the message is from
 +     * @param string $body message text
 +     * @return boolean true if the message was a command and was executed, false if it was not a command
 +     */
 +    protected function handle_command($user, $body)
 +    {
 +        $inter = new CommandInterpreter();
 +        $cmd = $inter->handle_command($user, $body);
 +        if ($cmd) {
 +            $chan = new IMChannel($this);
 +            $cmd->execute($chan);
 +            return true;
 +        } else {
 +            return false;
 +        }
 +    }
 +
 +    /**
 +     * Is some text an autoreply message?
 +     * @param string $txt message text
 +     * @return boolean true if autoreply
 +     */
 +    protected function is_autoreply($txt)
 +    {
 +        if (preg_match('/[\[\(]?[Aa]uto[-\s]?[Rr]e(ply|sponse)[\]\)]/', $txt)) {
 +            return true;
 +        } else if (preg_match('/^System: Message wasn\'t delivered. Offline storage size was exceeded.$/', $txt)) {
 +            return true;
 +        } else {
 +            return false;
 +        }
 +    }
 +
 +    /**
 +     * Is some text an OTR message?
 +     * @param string $txt message text
 +     * @return boolean true if OTR
 +     */
 +    protected function is_otr($txt)
 +    {
 +        if (preg_match('/^\?OTR/', $txt)) {
 +            return true;
 +        } else {
 +            return false;
 +        }
 +    }
 +
 +    /**
 +     * Helper for handling incoming messages
 +     * Your incoming message handler will probably want to call this function
 +     *
 +     * @param string $from screenname the message was sent from
 +     * @param string $message message contents
 +     *
 +     * @param boolean success
 +     */
 +    protected function handle_incoming($from, $notice_text)
 +    {
 +        $user = $this->get_user($from);
 +        // For common_current_user to work
 +        global $_cur;
 +        $_cur = $user;
 +
 +        if (!$user) {
 +            $this->send_from_site($from, 'Unknown user; go to ' .
 +                             common_local_url('imsettings') .
 +                             ' to add your address to your account');
 +            common_log(LOG_WARNING, 'Message from unknown user ' . $from);
 +            return;
 +        }
 +        if ($this->handle_command($user, $notice_text)) {
 +            common_log(LOG_INFO, "Command message by $from handled.");
 +            return;
 +        } else if ($this->is_autoreply($notice_text)) {
 +            common_log(LOG_INFO, 'Ignoring auto reply from ' . $from);
 +            return;
 +        } else if ($this->is_otr($notice_text)) {
 +            common_log(LOG_INFO, 'Ignoring OTR from ' . $from);
 +            return;
 +        } else {
 +
 +            common_log(LOG_INFO, 'Posting a notice from ' . $user->nickname);
 +
 +            $this->add_notice($from, $user, $notice_text);
 +        }
 +
 +        $user->free();
 +        unset($user);
 +        unset($_cur);
 +        unset($message);
 +    }
 +
 +    /**
 +     * Helper for handling incoming messages
 +     * Your incoming message handler will probably want to call this function
 +     *
 +     * @param string $from screenname the message was sent from
 +     * @param string $message message contents
 +     *
 +     * @param boolean success
 +     */
 +    protected function add_notice($screenname, $user, $body)
 +    {
 +        $body = trim(strip_tags($body));
 +        $content_shortened = common_shorten_links($body);
 +        if (Notice::contentTooLong($content_shortened)) {
 +          $this->send_from_site($screenname, sprintf(_('Message too long - maximum is %1$d characters, you sent %2$d.'),
 +                                          Notice::maxContent(),
 +                                          mb_strlen($content_shortened)));
 +          return;
 +        }
 +
 +        try {
 +            $notice = Notice::saveNew($user->id, $content_shortened, $this->transport);
 +        } catch (Exception $e) {
 +            common_log(LOG_ERR, $e->getMessage());
 +            $this->send_from_site($from, $e->getMessage());
 +            return;
 +        }
 +
 +        common_broadcast_notice($notice);
 +        common_log(LOG_INFO,
 +                   'Added notice ' . $notice->id . ' from user ' . $user->nickname);
 +        $notice->free();
 +        unset($notice);
 +    }
 +
 +    //========================EVENT HANDLERS========================\
 +    
 +    /**
 +     * Register notice queue handler
 +     *
 +     * @param QueueManager $manager
 +     *
 +     * @return boolean hook return
 +     */
 +    function onEndInitializeQueueManager($manager)
 +    {
 +        $manager->connect($this->transport . '-in', new ImReceiverQueueHandler($this), 'im');
 +        $manager->connect($this->transport, new ImQueueHandler($this));
 +        $manager->connect($this->transport . '-out', new ImSenderQueueHandler($this), 'im');
 +        return true;
 +    }
 +
 +    function onStartImDaemonIoManagers(&$classes)
 +    {
 +        //$classes[] = new ImManager($this); // handles sending/receiving/pings/reconnects
 +        return true;
 +    }
 +
 +    function onStartEnqueueNotice($notice, &$transports)
 +    {
 +        $profile = Profile::staticGet($notice->profile_id);
 +
 +        if (!$profile) {
 +            common_log(LOG_WARNING, 'Refusing to broadcast notice with ' .
 +                       'unknown profile ' . common_log_objstring($notice),
 +                       __FILE__);
 +        }else{
 +            $transports[] = $this->transport;
 +        }
 +
 +        return true;
 +    }
 +
 +    function onEndShowHeadElements($action)
 +    {
 +        $aname = $action->trimmed('action');
 +
 +        if ($aname == 'shownotice') {
 +
 +            $user_im_prefs = new User_im_prefs();
 +            $user_im_prefs->user_id = $action->profile->id;
 +            $user_im_prefs->transport = $this->transport;
 +
 +            if ($user_im_prefs->find() && $user_im_prefs->fetch() && $user_im_prefs->microid && $action->notice->uri) {
 +                $id = new Microid($this->microiduri($user_im_prefs->screenname),
 +                                  $action->notice->uri);
 +                $action->element('meta', array('name' => 'microid',
 +                                             'content' => $id->toString()));
 +            }
 +
 +        } else if ($aname == 'showstream') {
 +
 +            $user_im_prefs = new User_im_prefs();
 +            $user_im_prefs->user_id = $action->user->id;
 +            $user_im_prefs->transport = $this->transport;
 +
 +            if ($user_im_prefs->find() && $user_im_prefs->fetch() && $user_im_prefs->microid && $action->profile->profileurl) {
 +                $id = new Microid($this->microiduri($user_im_prefs->screenname),
 +                                  $action->selfUrl());
 +                $action->element('meta', array('name' => 'microid',
 +                                               'content' => $id->toString()));
 +            }
 +        }
 +    }
 +
 +    function onNormalizeImScreenname($transport, &$screenname)
 +    {
 +        if($transport == $this->transport)
 +        {
 +            $screenname = $this->normalize($screenname);
 +            return false;
 +        }
 +    }
 +
 +    function onValidateImScreenname($transport, $screenname, &$valid)
 +    {
 +        if($transport == $this->transport)
 +        {
 +            $valid = $this->validate($screenname);
 +            return false;
 +        }
 +    }
 +
 +    function onGetImTransports(&$transports)
 +    {
++        $transports[$this->transport] = array(
++            'display' => $this->getDisplayName(),
++            'daemon_screenname' => $this->daemon_screenname());
 +    }
 +
 +    function onSendImConfirmationCode($transport, $screenname, $code, $user)
 +    {
 +        if($transport == $this->transport)
 +        {
 +            $this->send_confirmation_code($screenname, $code, $user);
 +            return false;
 +        }
 +    }
 +
 +    function onUserDeleteRelated($user, &$tables)
 +    {
 +        $tables[] = 'User_im_prefs';
 +        return true;
 +    }
 +
 +    function initialize()
 +    {
 +        if(is_null($this->transport)){
 +            throw new Exception('transport cannot be null');
 +        }
 +    }
 +}
Simple merge
diff --cc lib/util.php
Simple merge