]> git.mxchange.org Git - quix0rs-gnu-social.git/blob - lib/mail.php
Notices start saving selfLink from activities/objects
[quix0rs-gnu-social.git] / lib / mail.php
1 <?php
2 /**
3  * StatusNet, the distributed open-source microblogging tool
4  *
5  * utilities for sending email
6  *
7  * PHP version 5
8  *
9  * LICENCE: This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU Affero General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Affero General Public License for more details.
18  *
19  * You should have received a copy of the GNU Affero General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  * @category  Mail
23  * @package   StatusNet
24  * @author    Evan Prodromou <evan@status.net>
25  * @author    Zach Copley <zach@status.net>
26  * @author    Robin Millette <millette@status.net>
27  * @author    Sarven Capadisli <csarven@status.net>
28  * @copyright 2008 StatusNet, Inc.
29  * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
30  * @link      http://status.net/
31  */
32
33 if (!defined('GNUSOCIAL')) { exit(1); }
34
35 require_once 'Mail.php';
36
37 /**
38  * return the configured mail backend
39  *
40  * Uses the $config array to make a mail backend. Cached so it is safe to call
41  * more than once.
42  *
43  * @return Mail backend
44  */
45 function mail_backend()
46 {
47     static $backend = null;
48     global $_PEAR;
49
50     if (!$backend) {
51         $mail = new Mail();
52         $backend = $mail->factory(common_config('mail', 'backend'),
53                                  common_config('mail', 'params') ?: array());
54         if ($_PEAR->isError($backend)) {
55             throw new EmailException($backend->getMessage(), $backend->getCode());
56         }
57     }
58     return $backend;
59 }
60
61 /**
62  * send an email to one or more recipients
63  *
64  * @param array  $recipients array of strings with email addresses of recipients
65  * @param array  $headers    array mapping strings to strings for email headers
66  * @param string $body       body of the email
67  *
68  * @return boolean success flag
69  */
70 function mail_send($recipients, $headers, $body)
71 {
72     global $_PEAR;
73
74     try {
75         // XXX: use Mail_Queue... maybe
76         $backend = mail_backend();
77
78         if (!isset($headers['Content-Type'])) {
79            $headers['Content-Type'] = 'text/plain; charset=UTF-8';
80         }
81
82         assert($backend); // throws an error if it's bad
83         $sent = $backend->send($recipients, $headers, $body);
84         if ($_PEAR->isError($sent)) {
85             throw new EmailException($sent->getMessage(), $sent->getCode());
86         }
87         return true;
88     } catch (PEAR_Exception $e) {
89         common_log(
90             LOG_ERR,
91             "Unable to send email - '{$e->getMessage()}'. "
92             . 'Is your mail subsystem set up correctly?'
93         );
94         return false;
95     }
96 }
97
98 /**
99  * returns the configured mail domain
100  *
101  * Defaults to the server name.
102  *
103  * @return string mail domain, suitable for making email addresses.
104  */
105 function mail_domain()
106 {
107     $maildomain = common_config('mail', 'domain');
108     if (!$maildomain) {
109         $maildomain = common_config('site', 'server');
110     }
111     return $maildomain;
112 }
113
114 /**
115  * returns a good address for sending email from this server
116  *
117  * Uses either the configured value or a faked-up value made
118  * from the mail domain.
119  *
120  * @return string notify from address
121  */
122 function mail_notify_from()
123 {
124     $notifyfrom = common_config('mail', 'notifyfrom');
125
126     if (!$notifyfrom) {
127
128         $domain = mail_domain();
129
130         $notifyfrom = '"'. str_replace('"', '\\"', common_config('site', 'name')) .'" <noreply@'.$domain.'>';
131     }
132
133     return $notifyfrom;
134 }
135
136 /**
137  * sends email to a user
138  *
139  * @param User   &$user   user to send email to
140  * @param string $subject subject of the email
141  * @param string $body    body of the email
142  * @param array  $headers optional list of email headers
143  * @param string $address optional specification of email address
144  *
145  * @return boolean success flag
146  */
147 function mail_to_user($user, $subject, $body, $headers=array(), $address=null)
148 {
149     if (!$address) {
150         $address = $user->email;
151     }
152
153     $recipients = $address;
154     $profile    = $user->getProfile();
155
156     $headers['Date']    = date("r", time());
157     $headers['From']    = mail_notify_from();
158     $headers['To']      = $profile->getBestName() . ' <' . $address . '>';
159     $headers['Subject'] = $subject;
160
161     return mail_send($recipients, $headers, $body);
162 }
163
164 /**
165  * notify a user of subscription by another user
166  *
167  * This is just a wrapper around the profile-based version.
168  *
169  * @param User $listenee user who is being subscribed to
170  * @param User $listener user who is subscribing
171  *
172  * @see mail_subscribe_notify_profile()
173  *
174  * @return void
175  */
176 function mail_subscribe_notify($listenee, $listener)
177 {
178     $other = $listener->getProfile();
179     mail_subscribe_notify_profile($listenee, $other);
180 }
181
182 /**
183  * notify a user of subscription by a profile (remote or local)
184  *
185  * This function checks to see if the listenee has an email
186  * address and wants subscription notices.
187  *
188  * @param User    $listenee user who's being subscribed to
189  * @param Profile $other    profile of person who's listening
190  *
191  * @return void
192  */
193 function mail_subscribe_notify_profile($listenee, $other)
194 {
195     if ($other->hasRight(Right::EMAILONSUBSCRIBE) &&
196         $listenee->email && $listenee->emailnotifysub) {
197
198         $profile = $listenee->getProfile();
199
200         $name = $profile->getBestName();
201
202         $long_name = $other->getFancyName();
203
204         $recipients = $listenee->email;
205
206         // use the recipient's localization
207         common_switch_locale($listenee->language);
208
209         $headers = _mail_prepare_headers('subscribe', $listenee->nickname, $other->nickname);
210         $headers['From']    = mail_notify_from();
211         $headers['To']      = $name . ' <' . $listenee->email . '>';
212         // TRANS: Subject of new-subscriber notification e-mail.
213         // TRANS: %1$s is the subscribing user's nickname, %2$s is the StatusNet sitename.
214         $headers['Subject'] = sprintf(_('%1$s is now following you on %2$s.'),
215                                       $other->getBestName(),
216                                       common_config('site', 'name'));
217
218         // TRANS: Main body of new-subscriber notification e-mail.
219         // TRANS: %1$s is the subscriber's long name, %2$s is the StatusNet sitename.
220         $body = sprintf(_('%1$s is now following you on %2$s.'),
221                         $long_name,
222                         common_config('site', 'name')) .
223                 mail_profile_block($other) .
224                 mail_footer_block();
225
226         // reset localization
227         common_switch_locale();
228         mail_send($recipients, $headers, $body);
229     }
230 }
231
232 function mail_subscribe_pending_notify_profile($listenee, $other)
233 {
234     if ($other->hasRight(Right::EMAILONSUBSCRIBE) &&
235         $listenee->email && $listenee->emailnotifysub) {
236
237         $profile = $listenee->getProfile();
238
239         $name = $profile->getBestName();
240
241         $long_name = ($other->fullname) ?
242           ($other->fullname . ' (' . $other->nickname . ')') : $other->nickname;
243
244         $recipients = $listenee->email;
245
246         // use the recipient's localization
247         common_switch_locale($listenee->language);
248
249         $headers = _mail_prepare_headers('subscribe', $listenee->nickname, $other->nickname);
250         $headers['From']    = mail_notify_from();
251         $headers['To']      = $name . ' <' . $listenee->email . '>';
252         // TRANS: Subject of pending new-subscriber notification e-mail.
253         // TRANS: %1$s is the subscribing user's nickname, %2$s is the StatusNet sitename.
254         $headers['Subject'] = sprintf(_('%1$s would like to listen to '.
255                                         'your notices on %2$s.'),
256                                       $other->getBestName(),
257                                       common_config('site', 'name'));
258
259         // TRANS: Main body of pending new-subscriber notification e-mail.
260         // TRANS: %1$s is the subscriber's long name, %2$s is the StatusNet sitename.
261         $body = sprintf(_('%1$s would like to listen to your notices on %2$s. ' .
262                           'You may approve or reject their subscription at %3$s'),
263                         $long_name,
264                         common_config('site', 'name'),
265                         common_local_url('subqueue', array('nickname' => $listenee->nickname))) .
266                 mail_profile_block($other) .
267                 mail_footer_block();
268
269         // reset localization
270         common_switch_locale();
271         mail_send($recipients, $headers, $body);
272     }
273 }
274
275 function mail_footer_block()
276 {
277     // TRANS: Common footer block for StatusNet notification emails.
278     // TRANS: %1$s is the StatusNet sitename,
279     // TRANS: %2$s is a link to the addressed user's e-mail settings.
280     return "\n\n" . sprintf(_('Faithfully yours,'.
281                               "\n".'%1$s.'."\n\n".
282                               "----\n".
283                               "Change your email address or ".
284                               "notification options at ".'%2$s'),
285                             common_config('site', 'name'),
286                             common_local_url('emailsettings')) . "\n";
287 }
288
289 /**
290  * Format a block of profile info for a plaintext notification email.
291  *
292  * @param Profile $profile
293  * @return string
294  */
295 function mail_profile_block($profile)
296 {
297     // TRANS: Layout for
298     // TRANS: %1$s is the subscriber's profile URL, %2$s is the subscriber's location (or empty)
299     // TRANS: %3$s is the subscriber's homepage URL (or empty), %4%s is the subscriber's bio (or empty)
300     $out = array();
301     $out[] = "";
302     $out[] = "";
303     // TRANS: Profile info line in notification e-mail.
304     // TRANS: %s is a URL.
305     $out[] = sprintf(_("Profile: %s"), $profile->profileurl);
306     if ($profile->location) {
307         // TRANS: Profile info line in notification e-mail.
308         // TRANS: %s is a location.
309         $out[] = sprintf(_("Location: %s"), $profile->location);
310     }
311     if ($profile->homepage) {
312         // TRANS: Profile info line in notification e-mail.
313         // TRANS: %s is a homepage.
314         $out[] = sprintf(_("Homepage: %s"), $profile->homepage);
315     }
316     if ($profile->bio) {
317         // TRANS: Profile info line in notification e-mail.
318         // TRANS: %s is biographical information.
319         $out[] = sprintf(_("Bio: %s"), $profile->bio);
320     }
321
322     $blocklink = common_local_url('block', array('profileid' => $profile->id));
323     // This'll let ModPlus add the remote profile info so it's possible
324     // to block remote users directly...
325     Event::handle('MailProfileInfoBlockLink', array($profile, &$blocklink));
326
327     // TRANS: This is a paragraph in a new-subscriber e-mail.
328     // TRANS: %s is a URL where the subscriber can be reported as abusive.
329     $out[] = sprintf(_('If you believe this account is being used abusively, ' .
330                        'you can block them from your subscribers list and ' .
331                        'report as spam to site administrators at %s.'),
332                      $blocklink);
333     $out[] = "";
334
335     return implode("\n", $out);
336 }
337
338 /**
339  * notify a user of their new incoming email address
340  *
341  * User's email and incoming fields should already be updated.
342  *
343  * @param User $user user with the new address
344  *
345  * @return void
346  */
347 function mail_new_incoming_notify($user)
348 {
349     $profile = $user->getProfile();
350
351     $name = $profile->getBestName();
352
353     $headers['From']    = $user->incomingemail;
354     $headers['To']      = $name . ' <' . $user->email . '>';
355     // TRANS: Subject of notification mail for new posting email address.
356     // TRANS: %s is the StatusNet sitename.
357     $headers['Subject'] = sprintf(_('New email address for posting to %s'),
358                                   common_config('site', 'name'));
359
360     // TRANS: Body of notification mail for new posting email address.
361     // TRANS: %1$s is the StatusNet sitename, %2$s is the e-mail address to send
362     // TRANS: to to post by e-mail, %3$s is a URL to more instructions.
363     $body = sprintf(_("You have a new posting address on %1\$s.\n\n".
364                       "Send email to %2\$s to post new messages.\n\n".
365                       "More email instructions at %3\$s."),
366                     common_config('site', 'name'),
367                     $user->incomingemail,
368                     common_local_url('doc', array('title' => 'email'))) .
369             mail_footer_block();
370
371     mail_send($user->email, $headers, $body);
372 }
373
374 /**
375  * generate a new address for incoming messages
376  *
377  * @todo check the database for uniqueness
378  *
379  * @return string new email address for incoming messages
380  */
381 function mail_new_incoming_address()
382 {
383     $prefix = common_confirmation_code(64);
384     $suffix = mail_domain();
385     return $prefix . '@' . $suffix;
386 }
387
388 /**
389  * broadcast a notice to all subscribers with SMS notification on
390  *
391  * This function sends SMS messages to all users who have sms addresses;
392  * have sms notification on; and have sms enabled for this particular
393  * subscription.
394  *
395  * @param Notice $notice The notice to broadcast
396  *
397  * @return success flag
398  */
399 function mail_broadcast_notice_sms($notice)
400 {
401     // Now, get users subscribed to this profile
402
403     $user = new User();
404
405     $UT = common_config('db','type')=='pgsql'?'"user"':'user';
406     $replies = $notice->getReplies();
407     $user->query('SELECT nickname, smsemail, incomingemail ' .
408                  "FROM $UT LEFT OUTER JOIN subscription " .
409                  "ON $UT.id = subscription.subscriber " .
410                  'AND subscription.subscribed = ' . $notice->profile_id . ' ' .
411                  'AND subscription.subscribed != subscription.subscriber ' .
412                  // Users (other than the sender) who `want SMS notices':
413                  "WHERE $UT.id != " . $notice->profile_id . ' ' .
414                  "AND $UT.smsemail IS NOT null " .
415                  "AND $UT.smsnotify = 1 " .
416                  // ... where either the user _is_ subscribed to the sender
417                  // (any of the "subscription" fields IS NOT null)
418                  // and wants to get SMS for all of this scribe's notices...
419                  'AND (subscription.sms = 1 ' .
420                  // ... or where the user was mentioned in
421                  // or replied-to with the notice:
422                  ($replies ? sprintf("OR $UT.id in (%s)",
423                                      implode(',', $replies))
424                            : '') .
425                  ')');
426
427     while ($user->fetch()) {
428         common_log(LOG_INFO,
429                    'Sending notice ' . $notice->id . ' to ' . $user->smsemail,
430                    __FILE__);
431         $success = mail_send_sms_notice_address($notice,
432                                                 $user->smsemail,
433                                                 $user->incomingemail,
434                                                 $user->nickname);
435         if (!$success) {
436             // XXX: Not sure, but I think that's the right thing to do
437             common_log(LOG_WARNING,
438                        'Sending notice ' . $notice->id . ' to ' .
439                        $user->smsemail . ' FAILED, cancelling.',
440                        __FILE__);
441             return false;
442         }
443     }
444
445     $user->free();
446     unset($user);
447
448     return true;
449 }
450
451 /**
452  * send a notice to a user via SMS
453  *
454  * A convenience wrapper around mail_send_sms_notice_address()
455  *
456  * @param Notice $notice notice to send
457  * @param User   $user   user to receive notice
458  *
459  * @see mail_send_sms_notice_address()
460  *
461  * @return boolean success flag
462  */
463 function mail_send_sms_notice($notice, $user)
464 {
465     return mail_send_sms_notice_address($notice,
466                                         $user->smsemail,
467                                         $user->incomingemail,
468                                         $user->nickname);
469 }
470
471 /**
472  * send a notice to an SMS email address from a given address
473  *
474  * We use the user's incoming email address as the "From" address to make
475  * replying to notices easier.
476  *
477  * @param Notice $notice        notice to send
478  * @param string $smsemail      email address to send to
479  * @param string $incomingemail email address to set as 'from'
480  * @param string $nickname      nickname to add to beginning
481  *
482  * @return boolean success flag
483  */
484 function mail_send_sms_notice_address($notice, $smsemail, $incomingemail, $nickname)
485 {
486     $to = $nickname . ' <' . $smsemail . '>';
487
488     $other = $notice->getProfile();
489
490     common_log(LOG_INFO, 'Sending notice ' . $notice->id .
491                ' to ' . $smsemail, __FILE__);
492
493     $headers = array();
494
495     $headers['From']    = ($incomingemail) ? $incomingemail : mail_notify_from();
496     $headers['To']      = $to;
497     // TRANS: Subject line for SMS-by-email notification messages.
498     // TRANS: %s is the posting user's nickname.
499     $headers['Subject'] = sprintf(_('%s status'),
500                                   $other->getBestName());
501
502     $body = $notice->content;
503
504     return mail_send($smsemail, $headers, $body);
505 }
506
507 /**
508  * send a message to confirm a claim for an SMS number
509  *
510  * @param string $code     confirmation code
511  * @param string $nickname nickname of user claiming number
512  * @param string $address  email address to send the confirmation to
513  *
514  * @see common_confirmation_code()
515  *
516  * @return void
517  */
518 function mail_confirm_sms($code, $nickname, $address)
519 {
520     $recipients = $address;
521
522     $headers['From']    = mail_notify_from();
523     $headers['To']      = $nickname . ' <' . $address . '>';
524     // TRANS: Subject line for SMS-by-email address confirmation message.
525     $headers['Subject'] = _('SMS confirmation');
526
527     // TRANS: Main body heading for SMS-by-email address confirmation message.
528     // TRANS: %s is the addressed user's nickname.
529     $body  = sprintf(_('%s: confirm you own this phone number with this code:'), $nickname);
530     $body .= "\n\n";
531     $body .= $code;
532     $body .= "\n\n";
533
534     mail_send($recipients, $headers, $body);
535 }
536
537 /**
538  * send a mail message to notify a user of a 'nudge'
539  *
540  * @param User $from user nudging
541  * @param User $to   user being nudged
542  *
543  * @return boolean success flag
544  */
545 function mail_notify_nudge($from, $to)
546 {
547     common_switch_locale($to->language);
548     // TRANS: Subject for 'nudge' notification email.
549     // TRANS: %s is the nudging user.
550     $subject = sprintf(_('You have been nudged by %s'), $from->nickname);
551
552     $from_profile = $from->getProfile();
553
554     // TRANS: Body for 'nudge' notification email.
555     // TRANS: %1$s is the nuding user's long name, $2$s is the nudging user's nickname,
556     // TRANS: %3$s is a URL to post notices at.
557     $body = sprintf(_("%1\$s (%2\$s) is wondering what you are up to ".
558                       "these days and is inviting you to post some news.\n\n".
559                       "So let's hear from you :)\n\n".
560                       "%3\$s\n\n".
561                       "Don't reply to this email; it won't get to them."),
562                     $from_profile->getBestName(),
563                     $from->nickname,
564                     common_local_url('all', array('nickname' => $to->nickname))) .
565             mail_footer_block();
566     common_switch_locale();
567
568     $headers = _mail_prepare_headers('nudge', $to->nickname, $from->nickname);
569
570     return mail_to_user($to, $subject, $body, $headers);
571 }
572
573 /**
574  * send a message to notify a user of a direct message (DM)
575  *
576  * This function checks to see if the recipient wants notification
577  * of DMs and has a configured email address.
578  *
579  * @param Message $message message to notify about
580  * @param User    $from    user sending message; default to sender
581  * @param User    $to      user receiving message; default to recipient
582  *
583  * @return boolean success code
584  */
585 function mail_notify_message($message, $from=null, $to=null)
586 {
587     if (is_null($from)) {
588         $from = User::getKV('id', $message->from_profile);
589     }
590
591     if (is_null($to)) {
592         $to = User::getKV('id', $message->to_profile);
593     }
594
595     if (is_null($to->email) || !$to->emailnotifymsg) {
596         return true;
597     }
598
599     common_switch_locale($to->language);
600     // TRANS: Subject for direct-message notification email.
601     // TRANS: %s is the sending user's nickname.
602     $subject = sprintf(_('New private message from %s'), $from->nickname);
603
604     $from_profile = $from->getProfile();
605
606     // TRANS: Body for direct-message notification email.
607     // TRANS: %1$s is the sending user's long name, %2$s is the sending user's nickname,
608     // TRANS: %3$s is the message content, %4$s a URL to the message,
609     $body = sprintf(_("%1\$s (%2\$s) sent you a private message:\n\n".
610                       "------------------------------------------------------\n".
611                       "%3\$s\n".
612                       "------------------------------------------------------\n\n".
613                       "You can reply to their message here:\n\n".
614                       "%4\$s\n\n".
615                       "Don't reply to this email; it won't get to them."),
616                     $from_profile->getBestName(),
617                     $from->nickname,
618                     $message->content,
619                     common_local_url('newmessage', array('to' => $from->id))) .
620             mail_footer_block();
621
622     $headers = _mail_prepare_headers('message', $to->nickname, $from->nickname);
623
624     common_switch_locale();
625     return mail_to_user($to, $subject, $body, $headers);
626 }
627
628 /**
629  * Notify a user that they have received an "attn:" message AKA "@-reply"
630  *
631  * @param Profile $rcpt  The Profile who recevied the notice, should be a local user
632  * @param Notice $notice The notice that was sent
633  *
634  * @return void
635  */
636 function mail_notify_attn(Profile $rcpt, Notice $notice)
637 {
638     if (!$rcpt->isLocal()) {
639         return;
640     }
641
642     $sender = $notice->getProfile();
643     if ($rcpt->sameAs($sender)) {
644         return;
645     }
646
647     // See if the notice's author who mentions this user is sandboxed
648     if (!$sender->hasRight(Right::EMAILONREPLY)) {
649         return;
650     }
651
652     // If the author has blocked the author, don't spam them with a notification.
653     if ($rcpt->hasBlocked($sender)) {
654         return;
655     }
656
657     $user = $rcpt->getUser();
658     if (!$user->receivesEmailNotifications()) {
659         return;
660     }
661
662     common_switch_locale($user->language);
663
664     if ($notice->hasConversation()) {
665         $conversationUrl = common_local_url('conversation',
666                          array('id' => $notice->conversation)).'#notice-'.$notice->getID();
667         // TRANS: Line in @-reply notification e-mail. %s is conversation URL.
668         $conversationEmailText = sprintf(_("The full conversation can be read here:\n\n".
669                                            "\t%s"), $conversationUrl) . "\n\n";
670     } else {
671         $conversationEmailText = '';
672     }
673
674     // TRANS: E-mail subject for notice notification.
675     // TRANS: %1$s is the "fancy name" for a profile.
676     $subject = sprintf(_('%1$s sent a notice to your attention'), $sender->getFancyName());
677
678         // TRANS: Body of @-reply notification e-mail.
679         // TRANS: %1$s is the sending user's name, $2$s is the StatusNet sitename,
680         // TRANS: %3$s is a URL to the notice, %4$s is the notice text,
681         // TRANS: %5$s is the text "The full conversation can be read here:" and a URL to the full conversion if it exists (otherwise empty),
682         // TRANS: %6$s is a URL to reply to the notice, %7$s is a URL to all @-replies for the addressed user,
683         $body = sprintf(_("%1\$s just sent a notice to your attention (an '@-reply') on %2\$s.\n\n".
684                       "The notice is here:\n\n".
685                       "\t%3\$s\n\n" .
686                       "It reads:\n\n".
687                       "\t%4\$s\n\n" .
688                       "%5\$s" .
689                       "You can reply back here:\n\n".
690                       "\t%6\$s\n\n" .
691                       "The list of all @-replies for you here:\n\n" .
692                       "%7\$s"),
693                     $sender->getFancyName(),//%1
694                     common_config('site', 'name'),//%2
695                     common_local_url('shownotice',
696                                      array('notice' => $notice->getID())),//%3
697                     $notice->getContent(),//%4
698                     $conversationEmailText,//%5
699                     common_local_url('newnotice',
700                                      array('replyto' => $sender->getNickname(), 'inreplyto' => $notice->getID())),//%6
701                     common_local_url('replies',
702                                      array('nickname' => $rcpt->getNickname()))) . //%7
703                 mail_footer_block();
704     $headers = _mail_prepare_headers('mention', $rcpt->getNickname(), $sender->getNickname());
705
706     common_switch_locale();
707     mail_to_user($user, $subject, $body, $headers);
708 }
709
710 /**
711  * Prepare the common mail headers used in notification emails
712  *
713  * @param string $msg_type type of message being sent to the user
714  * @param string $to       nickname of the receipient
715  * @param string $from     nickname of the user triggering the notification
716  *
717  * @return array list of mail headers to include in the message
718  */
719 function _mail_prepare_headers($msg_type, $to, $from)
720 {
721     $headers = array(
722         'X-StatusNet-MessageType' => $msg_type,
723         'X-StatusNet-TargetUser'  => $to,
724         'X-StatusNet-SourceUser'  => $from,
725         'X-StatusNet-Domain'      => common_config('site', 'server')
726     );
727
728     return $headers;
729 }
730
731 /**
732  * Send notification emails to group administrator.
733  *
734  * @param User_group $group
735  * @param Profile $joiner
736  */
737 function mail_notify_group_join($group, $joiner)
738 {
739     // This returns a Profile query...
740     $admin = $group->getAdmins();
741     while ($admin->fetch()) {
742         // We need a local user for email notifications...
743         $adminUser = User::getKV('id', $admin->id);
744         // @fixme check for email preference?
745         if ($adminUser && $adminUser->email) {
746             // use the recipient's localization
747             common_switch_locale($adminUser->language);
748
749             $headers = _mail_prepare_headers('join', $admin->nickname, $joiner->nickname);
750             $headers['From']    = mail_notify_from();
751             $headers['To']      = $admin->getBestName() . ' <' . $adminUser->email . '>';
752             // TRANS: Subject of group join notification e-mail.
753             // TRANS: %1$s is the joining user's nickname, %2$s is the group name, and %3$s is the StatusNet sitename.
754             $headers['Subject'] = sprintf(_('%1$s has joined '.
755                                             'your group %2$s on %3$s'),
756                                           $joiner->getBestName(),
757                                           $group->getBestName(),
758                                           common_config('site', 'name'));
759
760             // TRANS: Main body of group join notification e-mail.
761             // TRANS: %1$s is the subscriber's long name, %2$s is the group name, and %3$s is the StatusNet sitename,
762             // TRANS: %4$s is a block of profile info about the subscriber.
763             // TRANS: %5$s is a link to the addressed user's e-mail settings.
764             $body = sprintf(_('%1$s has joined your group %2$s on %3$s.'),
765                             $joiner->getFancyName(),
766                             $group->getFancyName(),
767                             common_config('site', 'name')) .
768                     mail_profile_block($joiner) .
769                     mail_footer_block();
770
771             // reset localization
772             common_switch_locale();
773             mail_send($adminUser->email, $headers, $body);
774         }
775     }
776 }
777
778
779 /**
780  * Send notification emails to group administrator.
781  *
782  * @param User_group $group
783  * @param Profile $joiner
784  */
785 function mail_notify_group_join_pending($group, $joiner)
786 {
787     $admin = $group->getAdmins();
788     while ($admin->fetch()) {
789         // We need a local user for email notifications...
790         $adminUser = User::getKV('id', $admin->id);
791         // @fixme check for email preference?
792         if ($adminUser && $adminUser->email) {
793             // use the recipient's localization
794             common_switch_locale($adminUser->language);
795
796             $headers = _mail_prepare_headers('join', $admin->nickname, $joiner->nickname);
797             $headers['From']    = mail_notify_from();
798             $headers['To']      = $admin->getBestName() . ' <' . $adminUser->email . '>';
799             // TRANS: Subject of pending group join request notification e-mail.
800             // TRANS: %1$s is the joining user's nickname, %2$s is the group name, and %3$s is the StatusNet sitename.
801             $headers['Subject'] = sprintf(_('%1$s wants to join your group %2$s on %3$s.'),
802                                           $joiner->getBestName(),
803                                           $group->getBestName(),
804                                           common_config('site', 'name'));
805
806             // TRANS: Main body of pending group join request notification e-mail.
807             // TRANS: %1$s is the subscriber's long name, %2$s is the group name, and %3$s is the StatusNet sitename,
808             // TRANS: %4$s is the URL to the moderation queue page.
809             $body = sprintf(_('%1$s would like to join your group %2$s on %3$s. ' .
810                               'You may approve or reject their group membership at %4$s'),
811                             $joiner->getFancyName(),
812                             $group->getFancyName(),
813                             common_config('site', 'name'),
814                             common_local_url('groupqueue', array('nickname' => $group->nickname))) .
815                     mail_profile_block($joiner) .
816                     mail_footer_block();
817
818             // reset localization
819             common_switch_locale();
820             mail_send($adminUser->email, $headers, $body);
821         }
822     }
823 }