X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Fjabber.php;h=e1bf06ba661bfc8a8e29bdc30637c5f3d8b22032;hb=72f72d17dbc2ddf5228d97079f992a99f2821373;hp=3dcdce5dbf349b87b629e9186bcb98ef519d22a9;hpb=df86aa721455fde537608d5faeaaf92075afb738;p=quix0rs-gnu-social.git diff --git a/lib/jabber.php b/lib/jabber.php index 3dcdce5dbf..e1bf06ba66 100644 --- a/lib/jabber.php +++ b/lib/jabber.php @@ -86,7 +86,32 @@ class Sharing_XMPP extends XMPPHP_XMPP } /** - * connect the configured Jabber account to the configured server + * Build an XMPP proxy connection that'll save outgoing messages + * to the 'xmppout' queue to be picked up by xmppdaemon later. + */ +function jabber_proxy() +{ + $proxy = new Queued_XMPP(common_config('xmpp', 'host') ? + common_config('xmpp', 'host') : + common_config('xmpp', 'server'), + common_config('xmpp', 'port'), + common_config('xmpp', 'user'), + common_config('xmpp', 'password'), + common_config('xmpp', 'resource') . 'daemon', + common_config('xmpp', 'server'), + common_config('xmpp', 'debug') ? + true : false, + common_config('xmpp', 'debug') ? + XMPPHP_Log::LEVEL_VERBOSE : null); + return $proxy; +} + +/** + * Lazy-connect the configured Jabber account to the configured server; + * if already opened, the same connection will be returned. + * + * In a multi-site background process, each site configuration + * will get its own connection. * * @param string $resource Resource to connect (defaults to configured resource) * @@ -95,16 +120,19 @@ class Sharing_XMPP extends XMPPHP_XMPP function jabber_connect($resource=null) { - static $conn = null; - if (!$conn) { + static $connections = array(); + $site = common_config('site', 'server'); + if (empty($connections[$site])) { + if (empty($resource)) { + $resource = common_config('xmpp', 'resource'); + } $conn = new Sharing_XMPP(common_config('xmpp', 'host') ? common_config('xmpp', 'host') : common_config('xmpp', 'server'), common_config('xmpp', 'port'), common_config('xmpp', 'user'), common_config('xmpp', 'password'), - ($resource) ? $resource : - common_config('xmpp', 'resource'), + $resource, common_config('xmpp', 'server'), common_config('xmpp', 'debug') ? true : false, @@ -115,12 +143,16 @@ function jabber_connect($resource=null) if (!$conn) { return false; } + $connections[$site] = $conn; $conn->autoSubscribe(); $conn->useEncryption(common_config('xmpp', 'encryption')); try { - $conn->connect(true); // true = persistent connection + common_log(LOG_INFO, __METHOD__ . ": connecting " . + common_config('xmpp', 'user') . '/' . $resource); + //$conn->connect(true); // true = persistent connection + $conn->connect(); // persistent connections break multisite } catch (XMPPHP_Exception $e) { common_log(LOG_ERR, $e->getMessage()); return false; @@ -128,11 +160,11 @@ function jabber_connect($resource=null) $conn->processUntil('session_start'); } - return $conn; + return $connections[$site]; } /** - * send a single notice to a given Jabber address + * Queue send for a single notice to a given Jabber address * * @param string $to JID to send the notice to * @param Notice $notice notice to send @@ -142,10 +174,7 @@ function jabber_connect($resource=null) function jabber_send_notice($to, $notice) { - $conn = jabber_connect(); - if (!$conn) { - return false; - } + $conn = jabber_proxy(); $profile = Profile::staticGet($notice->profile_id); if (!$profile) { common_log(LOG_WARNING, 'Refusing to send notice with ' . @@ -184,6 +213,11 @@ function jabber_format_entry($profile, $notice) } else { $xs->raw(common_render_content($notice->content, $notice)); } + $xs->text(" "); + $xs->element('a', array( + 'href'=>common_local_url('conversation', + array('id' => $notice->conversation)).'#notice-'.$notice->id + ),sprintf(_('[%s]'),$notice->id)); $xs->elementEnd('body'); $xs->elementEnd('html'); @@ -205,10 +239,7 @@ function jabber_format_entry($profile, $notice) function jabber_send_message($to, $body, $type='chat', $subject=null) { - $conn = jabber_connect(); - if (!$conn) { - return false; - } + $conn = jabber_proxy(); $conn->message($to, $body, $type, $subject); return true; } @@ -303,7 +334,7 @@ function jabber_special_presence($type, $to=null, $show=null, $status=null) } /** - * broadcast a notice to all subscribers and reply recipients + * Queue broadcast of a notice to all subscribers and reply recipients * * This function will send a notice to all subscribers on the local server * who have Jabber addresses, and have Jabber notification enabled, and @@ -327,7 +358,7 @@ function jabber_broadcast_notice($notice) common_log(LOG_WARNING, 'Refusing to broadcast notice with ' . 'unknown profile ' . common_log_objstring($notice), __FILE__); - return false; + return true; // not recoverable; discard. } $msg = jabber_format_notice($profile, $notice); @@ -338,84 +369,48 @@ function jabber_broadcast_notice($notice) $sent_to = array(); - $conn = jabber_connect(); + $conn = jabber_proxy(); - // First, get users to whom this is a direct reply - $user = new User(); - $UT = common_config('db','type')=='pgsql'?'"user"':'user'; - $user->query("SELECT $UT.id, $UT.jabber " . - "FROM $UT JOIN reply ON $UT.id = reply.profile_id " . - 'WHERE reply.notice_id = ' . $notice->id . ' ' . - "AND $UT.jabber is not null " . - "AND $UT.jabbernotify = 1 " . - "AND $UT.jabberreplies = 1 "); - - while ($user->fetch()) { - common_log(LOG_INFO, - 'Sending reply notice ' . $notice->id . ' to ' . $user->jabber, - __FILE__); - $conn->message($user->jabber, $msg, 'chat', null, $entry); - $conn->processTime(0); - $sent_to[$user->id] = 1; - } - - $user->free(); - - // Now, get users subscribed to this profile - - $user = new User(); - $user->query("SELECT $UT.id, $UT.jabber " . - "FROM $UT JOIN subscription " . - "ON $UT.id = subscription.subscriber " . - 'WHERE subscription.subscribed = ' . $notice->profile_id . ' ' . - "AND $UT.jabber is not null " . - "AND $UT.jabbernotify = 1 " . - 'AND subscription.jabber = 1 '); + $ni = $notice->whoGets(); - while ($user->fetch()) { - if (!array_key_exists($user->id, $sent_to)) { - common_log(LOG_INFO, - 'Sending notice ' . $notice->id . ' to ' . $user->jabber, - __FILE__); - $conn->message($user->jabber, $msg, 'chat', null, $entry); - // To keep the incoming queue from filling up, - // we service it after each send. - $conn->processTime(0); - $sent_to[$user->id] = 1; + foreach ($ni as $user_id => $reason) { + $user = User::staticGet($user_id); + if (empty($user) || + empty($user->jabber) || + !$user->jabbernotify) { + // either not a local user, or just not found + continue; } - } - - // Now, get users who have it in their inbox because of groups - - $user = new User(); - $user->query("SELECT $UT.id, $UT.jabber " . - "FROM $UT JOIN notice_inbox " . - "ON $UT.id = notice_inbox.user_id " . - 'WHERE notice_inbox.notice_id = ' . $notice->id . ' ' . - 'AND notice_inbox.source = 2 ' . - "AND $UT.jabber is not null " . - "AND $UT.jabbernotify = 1 "); - - while ($user->fetch()) { - if (!array_key_exists($user->id, $sent_to)) { - common_log(LOG_INFO, - 'Sending notice ' . $notice->id . ' to ' . $user->jabber, - __FILE__); - $conn->message($user->jabber, $msg, 'chat', null, $entry); - // To keep the incoming queue from filling up, - // we service it after each send. - $conn->processTime(0); - $sent_to[$user->id] = 1; + switch ($reason) { + case NOTICE_INBOX_SOURCE_REPLY: + if (!$user->jabberreplies) { + 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)); } - } - $user->free(); + common_log(LOG_INFO, + 'Sending notice ' . $notice->id . ' to ' . $user->jabber, + __FILE__); + $conn->message($user->jabber, $msg, 'chat', null, $entry); + } return true; } /** - * send a notice to all public listeners + * Queue send of 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. @@ -435,20 +430,20 @@ function jabber_public_notice($notice) // XXX: should we send out non-local messages if public,localonly // = false? I think not - if ($public && $notice->is_local) { + if ($public && $notice->is_local == Notice::LOCAL_PUBLIC) { $profile = Profile::staticGet($notice->profile_id); if (!$profile) { common_log(LOG_WARNING, 'Refusing to broadcast notice with ' . 'unknown profile ' . common_log_objstring($notice), __FILE__); - return false; + return true; // not recoverable; discard. } $msg = jabber_format_notice($profile, $notice); $entry = jabber_format_entry($profile, $notice); - $conn = jabber_connect(); + $conn = jabber_proxy(); foreach ($public as $address) { common_log(LOG_INFO, @@ -456,7 +451,6 @@ function jabber_public_notice($notice) ' to public listener ' . $address, __FILE__); $conn->message($address, $msg, 'chat', null, $entry); - $conn->processTime(0); } $profile->free(); } @@ -475,5 +469,5 @@ function jabber_public_notice($notice) function jabber_format_notice(&$profile, &$notice) { - return $profile->nickname . ': ' . $notice->content; + return $profile->nickname . ': ' . $notice->content . ' [' . $notice->id . ']'; }