diff --git a/classes/Notice.php b/classes/Notice.php index d65f0da9a9..42c235b1a3 100644 --- a/classes/Notice.php +++ b/classes/Notice.php @@ -981,8 +981,7 @@ class Notice extends Memcached_DataObject * messages, we won't deliver to any remote targets as that's the * source service's responsibility. * - * @fixme Unlike saveReplies() there's no mail notification here. - * Move that to distrib queue handler? + * Mail notifications etc will be handled later. * * @param array of unique identifier URIs for recipients */ @@ -1021,8 +1020,7 @@ class Notice extends Memcached_DataObject * and save reply records indicating that this message needs to be * delivered to those users. * - * Side effect: local recipients get e-mail notifications here. - * @fixme move mail notifications to distrib? + * Mail notifications to local profiles will be sent later. * * @return array of integer profile IDs */ @@ -1082,17 +1080,14 @@ class Notice extends Memcached_DataObject $recipientIds = array_keys($replied); - foreach ($recipientIds as $recipientId) { - $user = User::staticGet('id', $recipientId); - if (!empty($user)) { - self::blow('reply:stream:%d', $reply->profile_id); - mail_notify_attn($user, $this); - } - } - return $recipientIds; } + /** + * Pull the complete list of @-reply targets for this notice. + * + * @return array of integer profile ids + */ function getReplies() { // XXX: cache me @@ -1115,6 +1110,31 @@ class Notice extends Memcached_DataObject return $ids; } + /** + * Send e-mail notifications to local @-reply targets. + * + * Replies must already have been saved; this is expected to be run + * from the distrib queue handler. + */ + function sendReplyNotifications() + { + // Don't send reply notifications for repeats + + if (!empty($this->repeat_of)) { + return array(); + } + + $recipientIds = $this->getReplies(); + + foreach ($recipientIds as $recipientId) { + $user = User::staticGet('id', $recipientId); + if (!empty($user)) { + self::blow('reply:stream:%d', $recipientId); + mail_notify_attn($user, $this); + } + } + } + /** * Pull list of groups this notice needs to be delivered to, * as previously recorded by saveGroups() or saveKnownGroups(). diff --git a/doc-src/sms b/doc-src/sms index 1a3064318f..6cdccc6e97 100644 --- a/doc-src/sms +++ b/doc-src/sms @@ -1,4 +1,4 @@ -You can post messages to %%site.name%% using a many kinds of cell +You can post messages to %%site.name%% using many kinds of cell phones that support SMS messaging. This site does not support SMS directly; rather, it uses your carrier's email gateway to send and receive messages. diff --git a/lib/distribqueuehandler.php b/lib/distribqueuehandler.php index d2be7a92c7..8f4b72d5c3 100644 --- a/lib/distribqueuehandler.php +++ b/lib/distribqueuehandler.php @@ -49,25 +49,34 @@ class DistribQueueHandler } /** - * Here's the meat of your queue handler -- you're handed a Notice - * object, which you may do as you will with. + * Handle distribution of a notice after we've saved it: + * @li add to local recipient inboxes + * @li send email notifications to local @-reply targets + * @li run final EndNoticeSave plugin events + * @li put any remaining post-processing into the queues * * If this function indicates failure, a warning will be logged * and the item is placed back in the queue to be re-run. * + * @fixme addToInboxes is known to fail sometimes with large recipient sets + * * @param Notice $notice * @return boolean true on success, false on failure */ function handle($notice) { - // XXX: do we need to change this for remote users? - try { $notice->addToInboxes(); } catch (Exception $e) { $this->logit($notice, $e); } + try { + $notice->sendReplyNotifications(); + } catch (Exception $e) { + $this->logit($notice, $e); + } + try { Event::handle('EndNoticeSave', array($notice)); // Enqueue for other handlers diff --git a/lib/installer.php b/lib/installer.php index d0e46f95c8..589a19a66e 100644 --- a/lib/installer.php +++ b/lib/installer.php @@ -51,7 +51,7 @@ abstract class Installer public static $dbModules = array( 'mysql' => array( 'name' => 'MySQL', - 'check_module' => 'mysql', // mysqli? + 'check_module' => 'mysqli', 'installer' => 'mysql_db_installer', ), 'pgsql' => array( @@ -341,7 +341,6 @@ abstract class Installer * @param string $password * @return mixed array of database connection params on success, false on failure * - * @fixme be consistent about using mysqli vs mysql! * @fixme escape things in the connection string in case we have a funny pass etc */ function Mysql_Db_installer($host, $database, $username, $password) @@ -349,14 +348,13 @@ abstract class Installer $this->updateStatus("Starting installation..."); $this->updateStatus("Checking database..."); - $conn = mysql_connect($host, $username, $password); - if (!$conn) { + $conn = mysqli_init(); + if (!$conn->real_connect($host, $username, $password)) { $this->updateStatus("Can't connect to server '$host' as '$username'.", true); return false; } $this->updateStatus("Changing to database..."); - $res = mysql_select_db($database, $conn); - if (!$res) { + if (!$conn->select_db($database)) { $this->updateStatus("Can't change to database.", true); return false; } @@ -438,9 +436,9 @@ abstract class Installer // FIXME: use PEAR::DB or PDO instead of our own switch switch ($type) { case 'mysqli': - $res = mysql_query($stmt, $conn); + $res = $conn->query($stmt); if ($res === false) { - $error = mysql_error(); + $error = $conn->error(); } break; case 'pgsql': diff --git a/lib/mail.php b/lib/mail.php index c38d9f2f50..5fc584e28a 100644 --- a/lib/mail.php +++ b/lib/mail.php @@ -636,7 +636,7 @@ function mail_notify_attn($user, $notice) $bestname = $sender->getBestName(); - common_init_locale($user->language); + common_switch_locale($user->language); if ($notice->hasConversation()) { $conversationUrl = common_local_url('conversation', @@ -679,7 +679,7 @@ function mail_notify_attn($user, $notice) $headers = _mail_prepare_headers('mention', $user->nickname, $sender->nickname); - common_init_locale(); + common_switch_locale(); mail_to_user($user, $subject, $body, $headers); } diff --git a/lib/util.php b/lib/util.php index b11bb06e3c..81920eb447 100644 --- a/lib/util.php +++ b/lib/util.php @@ -41,11 +41,13 @@ function common_init_locale($language=null) } putenv('LANGUAGE='.$language); putenv('LANG='.$language); - return setlocale(LC_ALL, $language . ".utf8", + $ok = setlocale(LC_ALL, $language . ".utf8", $language . ".UTF8", $language . ".utf-8", $language . ".UTF-8", $language); + + return $ok; } function common_init_language() @@ -89,6 +91,14 @@ function common_init_language() $locale_set = common_init_locale($language); } + common_init_gettext(); +} + +/** + * @access private + */ +function common_init_gettext() +{ setlocale(LC_CTYPE, 'C'); // So we do not have to make people install the gettext locales $path = common_config('site','locale_path'); @@ -97,6 +107,25 @@ function common_init_language() textdomain("statusnet"); } +/** + * Switch locale during runtime, and poke gettext until it cries uncle. + * Otherwise, sometimes it doesn't actually switch away from the old language. + * + * @param string $language code for locale ('en', 'fr', 'pt_BR' etc) + */ +function common_switch_locale($language=null) +{ + common_init_locale($language); + + setlocale(LC_CTYPE, 'C'); + // So we do not have to make people install the gettext locales + $path = common_config('site','locale_path'); + bindtextdomain("statusnet", $path); + bind_textdomain_codeset("statusnet", "UTF-8"); + textdomain("statusnet"); +} + + function common_timezone() { if (common_logged_in()) { diff --git a/scripts/commandline.inc b/scripts/commandline.inc index 9029bb19db..a475e11d01 100644 --- a/scripts/commandline.inc +++ b/scripts/commandline.inc @@ -123,6 +123,10 @@ require_once INSTALLDIR . '/lib/common.php'; set_error_handler('common_error_handler'); +// Set up the language infrastructure so we can localize anything that +// needs to be sent out to users, such as mail notifications. +common_init_language(); + function _make_matches($opt, $alt) { $matches = array();