X-Git-Url: https://git.cyclocoop.org/%7B%24www_url%7Dadmin/compta/banques/?a=blobdiff_plain;f=includes%2FUserMailer.php;h=8953d7abb88621c2351099a81a8b665cfe571a7c;hb=a3b490d2c4dfc25d7e0594eae8ee27ba69f6afea;hp=80eb445c72c3c4184cdb690dbdc707e0fbaebb69;hpb=aed4a04076a27de87953dd766fdd34b8dd0213d0;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/UserMailer.php b/includes/UserMailer.php index 80eb445c72..8953d7abb8 100644 --- a/includes/UserMailer.php +++ b/includes/UserMailer.php @@ -16,48 +16,56 @@ * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * http://www.gnu.org/copyleft/gpl.html - * + * * @author * @author - * + * * @package MediaWiki */ -require_once( 'WikiError.php' ); - /** - * Provide mail capabilities - * @param string $string ???? - * - * The function takes formats like "name " into account, for which - * the partial string "name" will be quoted-printable converted but not - * "". - * - * The php mail() function does not accept the email address partial string to - * be quotedprintable, it does not accept inputs as - * quotedprintable("name ") . - * - * case 1: - * input: "name rest" - * output: "quoted-printable(name) " - * - * case 2: (should not happen) - * input: " rest" - * output: "" - * - * case 3: (should not happen) - * input: "name" - * output: "quoted-printable(name)" + * Converts a string into a valid RFC 822 "phrase", such as is used for the sender name */ -function wfQuotedPrintable_name_and_emailaddr( $string ) { +function wfRFC822Phrase( $phrase ) { + $phrase = strtr( $phrase, array( "\r" => '', "\n" => '', '"' => '' ) ); + return '"' . $phrase . '"'; +} + +class MailAddress { + /** + * @param mixed $address String with an email address, or a User object + * @param string $name Human-readable name if a string address is given + */ + function MailAddress( $address, $name=null ) { + if( is_object( $address ) && is_a( $address, 'User' ) ) { + $this->address = $address->getEmail(); + $this->name = $address->getName(); + } else { + $this->address = strval( $address ); + $this->name = strval( $name ); + } + } - /* do not quote printable for email address string , but only for the (leading) string, usually the name */ - preg_match( '/^([^<]*)?(<([A-z0-9_.-]+([A-z0-9_.-]+)*\@[A-z0-9_-]+([A-z0-9_.-]+)*([A-z.]{2,})+)>)?$/', $string, $part ); - if ( !isset($part[1]) ) return $part[2]; - if ( !isset($part[2]) ) return wfQuotedprintable($part[1]); - return wfQuotedprintable($part[1]) . $part[2] ; + /** + * Return formatted and quoted address to insert into SMTP headers + * @return string + */ + function toString() { + # PHP's mail() implementation under Windows is somewhat shite, and + # can't handle "Joe Bloggs " format email addresses, + # so don't bother generating them + if( $this->name != '' && !wfIsWindows() ) { + $quoted = wfQuotedPrintable( $this->name ); + if( strpos( $quoted, '.' ) !== false ) { + $quoted = '"' . $quoted . '"'; + } + return "$quoted <{$this->address}>"; + } else { + return $this->address; + } + } } /** @@ -66,77 +74,100 @@ function wfQuotedPrintable_name_and_emailaddr( $string ) { * array of parameters. It requires PEAR:Mail to do that. * Otherwise it just uses the standard PHP 'mail' function. * - * @param string $to recipient's email - * @param string $from sender's email - * @param string $subject email's subject - * @param string $body email's text - * @param string $replyto optional reply-to email (default : false) + * @param $to MailAddress: recipient's email + * @param $from MailAddress: sender's email + * @param $subject String: email's subject. + * @param $body String: email's text. + * @param $replyto String: optional reply-to email (default: false). */ function userMailer( $to, $from, $subject, $body, $replyto=false ) { - global $wgUser, $wgSMTP, $wgOutputEncoding, $wgErrorString, $wgEmergencyContact; - - $qto = wfQuotedPrintable_name_and_emailaddr( $to ); - + global $wgUser, $wgSMTP, $wgOutputEncoding, $wgErrorString; + if (is_array( $wgSMTP )) { require_once( 'Mail.php' ); - + $timestamp = time(); - - $headers['From'] = $from; -/* removing to: field as it should be set by the send() function below - UNTESTED - Hashar */ -// $headers['To'] = $qto; -/* Reply-To: - UNTESTED - Tom Gries */ - $headers['Reply-To'] = $replyto; - $headers['Subject'] = $subject; + $dest = $to->address; + + $headers['From'] = $from->toString(); + $headers['To'] = $to->toString(); + if ( $replyto ) { + $headers['Reply-To'] = $replyto; + } + $headers['Subject'] = wfQuotedPrintable( $subject ); + $headers['Date'] = date( 'r' ); $headers['MIME-Version'] = '1.0'; $headers['Content-type'] = 'text/plain; charset='.$wgOutputEncoding; $headers['Content-transfer-encoding'] = '8bit'; - $headers['Message-ID'] = "<{$timestamp}" . $wgUser->getName() . '@' . $wgSMTP['IDHost'] . '>'; + $headers['Message-ID'] = "<{$timestamp}" . $wgUser->getName() . '@' . $wgSMTP['IDHost'] . '>'; // FIXME $headers['X-Mailer'] = 'MediaWiki mailer'; - + // Create the mail object using the Mail::factory method $mail_object =& Mail::factory('smtp', $wgSMTP); - - $mailResult =& $mail_object->send($to, $headers, $body); - - # Based on the result return an error string, - if ($mailResult === true) + if( PEAR::isError( $mail_object ) ) { + wfDebug( "PEAR::Mail factory failed: " . $mail_object->getMessage() . "\n" ); + return $mail_object->getMessage(); + } + + wfDebug( "Sending mail via PEAR::Mail to $dest\n" ); + $mailResult =& $mail_object->send($dest, $headers, $body); + + # Based on the result return an error string, + if ($mailResult === true) { return ''; - else if (is_object($mailResult)) + } elseif (is_object($mailResult)) { + wfDebug( "PEAR::Mail failed: " . $mailResult->getMessage() . "\n" ); return $mailResult->getMessage(); - else + } else { + wfDebug( "PEAR::Mail failed, unknown error result\n" ); return 'Mail object return unknown error.'; + } } else { # In the following $headers = expression we removed "Reply-To: {$from}\r\n" , because it is treated differently # (fifth parameter of the PHP mail function, see some lines below) + + # Line endings need to be different on Unix and Windows due to + # the bug described at http://trac.wordpress.org/ticket/2603 + if ( wfIsWindows() ) { + $body = str_replace( "\n", "\r\n", $body ); + $endl = "\r\n"; + } else { + $endl = "\n"; + } $headers = - "MIME-Version: 1.0\n" . - "Content-type: text/plain; charset={$wgOutputEncoding}\n" . - "Content-Transfer-Encoding: 8bit\n" . - "X-Mailer: MediaWiki mailer\n". - 'From:' . wfQuotedPrintable_name_and_emailaddr($from) . "\n"; + "MIME-Version: 1.0$endl" . + "Content-type: text/plain; charset={$wgOutputEncoding}$endl" . + "Content-Transfer-Encoding: 8bit$endl" . + "X-Mailer: MediaWiki mailer$endl". + 'From: ' . $from->toString(); if ($replyto) { - $headers .= 'Reply-To: '.wfQuotedPrintable_name_and_emailaddr($replyto)."\n"; + $headers .= "{$endl}Reply-To: $replyto"; } + $dest = $to->toString(); + $wgErrorString = ''; set_error_handler( 'mailErrorHandler' ); - # added -f parameter, see PHP manual for the fifth parameter when using the mail function - mail( wfQuotedPrintable_name_and_emailaddr($to), $subject, $body, $headers, "-f{$wgEmergencyContact}\n"); + wfDebug( "Sending mail via internal mail() function to $dest\n" ); + mail( $dest, wfQuotedPrintable( $subject ), $body, $headers ); restore_error_handler(); + if ( $wgErrorString ) { + wfDebug( "Error sending mail: $wgErrorString\n" ); + } return $wgErrorString; } } /** - * @todo document + * Get the mail error message in global $wgErrorString + * + * @param $code Integer: error number + * @param $string String: error message */ function mailErrorHandler( $code, $string ) { global $wgErrorString; - $wgErrorString = preg_replace( "/^mail\(\): /", "", $string ); + $wgErrorString = preg_replace( '/^mail\(\)(\s*\[.*?\])?: /', '', $string ); } @@ -157,217 +188,217 @@ function mailErrorHandler( $code, $string ) { * same timeoffset in their preferences. * * Visit the documentation pages under http://meta.wikipedia.com/Enotif - * + * * @package MediaWiki - * + * */ class EmailNotification { - /**#@+ - * @access private + /**@{{ + * @private */ var $to, $subject, $body, $replyto, $from; - /**#@-*/ - + var $user, $title, $timestamp, $summary, $minorEdit, $oldid; + + /**@}}*/ + /** * @todo document - * @param $currentUser - * @param $currentPage - * @param $currentNs + * @param $title Title object * @param $timestamp - * @param $currentSummary - * @param $currentMinorEdit + * @param $summary + * @param $minorEdit * @param $oldid (default: false) */ - function NotifyOnPageChange($currentUser, $currentPage, $currentNs, $timestamp, $currentSummary, $currentMinorEdit, $oldid=false) { - + function notifyOnPageChange(&$title, $timestamp, $summary, $minorEdit, $oldid=false) { + # we use $wgEmergencyContact as sender's address - global $wgUser, $wgLang, $wgEmergencyContact; - global $wgEmailNotificationForWatchlistPages, $wgEmailNotificationForMinorEdits; - global $wgEmailNotificationSystembeep, $wgEmailNotificationForUserTalkPages; - global $wgEmailNotificationRevealPageEditorAddress; - global $wgEmailNotificationMailsSentFromPageEditor; - global $wgEmailAuthentication; - global $beeped; - + global $wgUser, $wgEnotifWatchlist; + global $wgEnotifMinorEdits, $wgEnotifUserTalk, $wgShowUpdatedMarker; + + $fname = 'UserMailer::notifyOnPageChange'; + wfProfileIn( $fname ); + # The following code is only run, if several conditions are met: # 1. EmailNotification for pages (other than user_talk pages) must be enabled # 2. minor edits (changes) are only regarded if the global flag indicates so - - $isUserTalkPage = ($currentNs == NS_USER_TALK); - $enotifusertalkpage = ($isUserTalkPage && $wgEmailNotificationForUserTalkPages); - $enotifwatchlistpage = (!$isUserTalkPage && $wgEmailNotificationForWatchlistPages); - - if ( ($enotifusertalkpage || $enotifwatchlistpage) - && (!$currentMinorEdit || $wgEmailNotificationForMinorEdits) ) { - - $dbr =& wfGetDB( DB_MASTER ); - extract( $dbr->tableNames( 'watchlist' ) ); - $sql = "SELECT wl_user FROM $watchlist - WHERE wl_title='" . $dbr->strencode($currentPage)."' AND wl_namespace = " . $currentNs . - " AND wl_user <>" . $currentUser . " AND wl_notificationtimestamp <= 1"; - $res = $dbr->query( $sql,'UserMailer::NotifyOnChange'); - - # if anyone is watching ... set up the email message text which is - # common for all receipients ... - if ( $dbr->numRows( $res ) > 0 ) { - - # This is a switch for one beep on the server when sending notification mails - $beeped = false; - - $article->mTimestamp = $timestamp; - $article->mSummary = $currentSummary; - $article->mMinorEdit = $currentMinorEdit; - $article->mNamespace = $currentNs; - $article->mTitle = $currentPage; - $article->mOldid = $oldid; - - $mail = $this->composeCommonMailtext( $wgUser, $article ); - $watchingUser = new User(); - - # ... now do for all watching users ... if the options fit - for ($i = 1; $i <= $dbr->numRows( $res ); $i++) { - - $wuser = $dbr->fetchObject( $res ); - $watchingUser->setID($wuser->wl_user); - if ( ( $enotifwatchlistpage && $watchingUser->getOption('enotifwatchlistpages') ) || - ( $enotifusertalkpage && $watchingUser->getOption('enotifusertalkpages') ) - && (!$currentMinorEdit || ($wgEmailNotificationForMinorEdits && $watchingUser->getOption('enotifminoredits') ) ) - && ($watchingUser->isEmailConfirmed() ) ) { - # ... adjust remaining text and page edit time placeholders - # which needs to be personalized for each user - $sent = $this->composeAndSendPersonalisedMail( $watchingUser, $mail, $article ); - /* the beep here beeps once when a watched-listed page is changed */ - if ($sent && !$beeped && ($wgEmailNotificationSystembeep != '') ) { - $last_line = system($wgEmailNotificationSystembeep); - $beeped=true; - } - } # if the watching user has an email address in the preferences - # mark the changed watch-listed page with a timestamp, so that the page is listed with an "updated since your last visit" icon in the watch list, ... - # ... no matter, if the watching user has or has not indicated an email address in his/her preferences. - # We memorise the event of sending out a notification and use this as a flag to suppress further mails for changes on the same page for that watching user - $dbw =& wfGetDB( DB_MASTER ); - $succes = $dbw->update( 'watchlist', - array( /* SET */ - 'wl_notificationtimestamp' => $article->mTimestamp - ), array( /* WHERE */ - 'wl_title' => $currentPage, - 'wl_namespace' => $currentNs, - 'wl_user' => $wuser->wl_user - ), 'UserMailer::NotifyOnChange' - ); - } # for every watching user + + $isUserTalkPage = ($title->getNamespace() == NS_USER_TALK); + $enotifusertalkpage = ($isUserTalkPage && $wgEnotifUserTalk); + $enotifwatchlistpage = $wgEnotifWatchlist; + + if ( (!$minorEdit || $wgEnotifMinorEdits) ) { + if( $wgEnotifWatchlist ) { + // Send updates to watchers other than the current editor + $userCondition = 'wl_user <> ' . intval( $wgUser->getId() ); + } elseif( $wgEnotifUserTalk && $title->getNamespace() == NS_USER_TALK ) { + $targetUser = User::newFromName( $title->getText() ); + if( is_null( $targetUser ) ) { + wfDebug( "$fname: user-talk-only mode; no such user\n" ); + $userCondition = false; + } elseif( $targetUser->getId() == $wgUser->getId() ) { + wfDebug( "$fname: user-talk-only mode; editor is target user\n" ); + $userCondition = false; + } else { + // Don't notify anyone other than the owner of the talk page + $userCondition = 'wl_user = ' . intval( $targetUser->getId() ); + } + } else { + // Notifications disabled + $userCondition = false; + } + if( $userCondition ) { + $dbr =& wfGetDB( DB_MASTER ); + extract( $dbr->tableNames( 'watchlist' ) ); + + $res = $dbr->select( 'watchlist', array( 'wl_user' ), + array( + 'wl_title' => $title->getDBkey(), + 'wl_namespace' => $title->getNamespace(), + $userCondition, + 'wl_notificationtimestamp IS NULL', + ), $fname ); + + # if anyone is watching ... set up the email message text which is + # common for all receipients ... + if ( $dbr->numRows( $res ) > 0 ) { + $this->title =& $title; + $this->timestamp = $timestamp; + $this->summary = $summary; + $this->minorEdit = $minorEdit; + $this->oldid = $oldid; + + $this->composeCommonMailtext(); + $watchingUser = new User(); + + # ... now do for all watching users ... if the options fit + for ($i = 1; $i <= $dbr->numRows( $res ); $i++) { + + $wuser = $dbr->fetchObject( $res ); + $watchingUser->setID($wuser->wl_user); + + if ( ( $enotifwatchlistpage && $watchingUser->getOption('enotifwatchlistpages') ) || + ( $enotifusertalkpage + && $watchingUser->getOption('enotifusertalkpages') + && $title->equals( $watchingUser->getTalkPage() ) ) + && (!$minorEdit || ($wgEnotifMinorEdits && $watchingUser->getOption('enotifminoredits') ) ) + && ($watchingUser->isEmailConfirmed() ) ) { + # ... adjust remaining text and page edit time placeholders + # which needs to be personalized for each user + $this->composeAndSendPersonalisedMail( $watchingUser ); + + } # if the watching user has an email address in the preferences + } + } } # if anyone is watching - } # if $wgEmailNotificationForWatchlistPages = true + } # if $wgEnotifWatchlist = true + + if ( $wgShowUpdatedMarker || $wgEnotifWatchlist ) { + # mark the changed watch-listed page with a timestamp, so that the page is + # listed with an "updated since your last visit" icon in the watch list, ... + $dbw =& wfGetDB( DB_MASTER ); + $success = $dbw->update( 'watchlist', + array( /* SET */ + 'wl_notificationtimestamp' => $dbw->timestamp($timestamp) + ), array( /* WHERE */ + 'wl_title' => $title->getDBkey(), + 'wl_namespace' => $title->getNamespace(), + ), 'UserMailer::NotifyOnChange' + ); + # FIXME what do we do on failure ? + } + wfProfileOut( $fname ); } # function NotifyOnChange - + /** - * @param User $pageeditorUser - * @param Article $article - * @access private + * @private */ - function composeCommonMailtext( $pageeditorUser, $article ) { - global $wgLang, $wgEmergencyContact; - global $wgEmailNotificationRevealPageEditorAddress; - global $wgEmailNotificationMailsSentFromPageEditor; - global $wgNoReplyAddress; - - $summary = ($article->mSummary == '') ? ' - ' : $article->mSummary; - $medit = ($article->mMinorEdit) ? wfMsg( 'minoredit' ) : ''; - + function composeCommonMailtext() { + global $wgUser, $wgEmergencyContact, $wgNoReplyAddress; + global $wgEnotifFromEditor, $wgEnotifRevealEditorAddress; + + $summary = ($this->summary == '') ? ' - ' : $this->summary; + $medit = ($this->minorEdit) ? wfMsg( 'minoredit' ) : ''; + # You as the WikiAdmin and Sysops can make use of plenty of # named variables when composing your notification emails while # simply editing the Meta pages - - $to = wfMsg( 'email_notification_to' ); - $subject = wfMsg( 'email_notification_subject' ); - $body = wfMsg( 'email_notification_body' ); + + $subject = wfMsgForContent( 'enotif_subject' ); + $body = wfMsgForContent( 'enotif_body' ); $from = ''; /* fail safe */ $replyto = ''; /* fail safe */ $keys = array(); - + # regarding the use of oldid as an indicator for the last visited version, see also # http://bugzilla.wikipeda.org/show_bug.cgi?id=603 "Delete + undelete cycle doesn't preserve old_id" # However, in the case of a new page which is already watched, we have no previous version to compare - if( $article->mOldid ) { - $keys['$NEWPAGE'] = wfMsg( 'email_notification_lastvisitedrevisiontext' ); - $keys['$OLDID'] = $article->mOldid; + if( $this->oldid ) { + $difflink = $this->title->getFullUrl( 'diff=0&oldid=' . $this->oldid ); + $keys['$NEWPAGE'] = wfMsgForContent( 'enotif_lastvisited', $difflink ); + $keys['$OLDID'] = $this->oldid; + $keys['$CHANGEDORCREATED'] = wfMsgForContent( 'changed' ); } else { - $keys['$NEWPAGE'] = wfMsg( 'email_notification_newpagetext' ); + $keys['$NEWPAGE'] = wfMsgForContent( 'enotif_newpagetext' ); # clear $OLDID placeholder in the message template $keys['$OLDID'] = ''; + $keys['$CHANGEDORCREATED'] = wfMsgForContent( 'created' ); } - - $body = strtr( $body, $keys ); - - $pagetitle = $article->mTitle; - if( $article->mNamespace != NS_MAIN ) { - $pagetitle = $wgLang->getNsText( $article->mNamespace ) . ':' . $pagetitle; - } - $subject = str_replace( '$PAGETITLE', str_replace( '_', ' ', $pagetitle ) , $subject); - $keys['%24PAGETITLE_RAWURL'] = wfUrlencode( $pagetitle ); - $keys['$PAGETITLE_RAWURL'] = wfUrlencode( $pagetitle ); - $keys['%24PAGETITLE'] = $pagetitle; # needed for the {{localurl:$PAGETITLE}} in the messagetext, "$" appears here as "%24" + + $body = strtr( $body, $keys ); + $pagetitle = $this->title->getPrefixedText(); $keys['$PAGETITLE'] = $pagetitle; - $keys['$PAGETIMESTAMP'] = $article->mTimestamp; # this is the raw internal timestamp - can be useful, too - $keys['$PAGEEDITDATEUTC'] = $wgLang->timeanddate( $article->mTimestamp, false, false, false ); + $keys['$PAGETITLE_URL'] = $this->title->getFullUrl(); + $keys['$PAGEMINOREDIT'] = $medit; $keys['$PAGESUMMARY'] = $summary; - + + $subject = strtr( $subject, $keys ); # Reveal the page editor's address as REPLY-TO address only if # the user has not opted-out and the option is enabled at the # global configuration level. - $name = $pageeditorUser->getName(); - $adminAddress = 'WikiAdmin <' . $wgEmergencyContact . '>'; - $editorAddress = $name . ' <' . $pageeditorUser->getEmail() . '>'; - if( $wgEmailNotificationRevealPageEditorAddress - && ( $pageeditorUser->getEmail() != '' ) - && $pageeditorUser->getOption( 'enotifrevealaddr' ) ) { - if( $wgEmailNotificationMailsSentFromPageEditor ) { + $name = $wgUser->getName(); + $adminAddress = new MailAddress( $wgEmergencyContact, 'WikiAdmin' ); + $editorAddress = new MailAddress( $wgUser ); + if( $wgEnotifRevealEditorAddress + && ( $wgUser->getEmail() != '' ) + && $wgUser->getOption( 'enotifrevealaddr' ) ) { + if( $wgEnotifFromEditor ) { $from = $editorAddress; } else { $from = $adminAddress; $replyto = $editorAddress; } - $keys['$PAGEEDITORNAMEANDEMAILADDR'] = $editorAddress; } else { $from = $adminAddress; $replyto = $wgNoReplyAddress; - $keys['$PAGEEDITORNAMEANDEMAILADDR'] = $replyto; } - - if( $pageeditorUser->isIP( $name ) ) { + + if( $wgUser->isIP( $name ) ) { #real anon (user:xxx.xxx.xxx.xxx) - $anon = $name . ' (anonymous user)'; - $anonUrl = wfUrlencode( $name ) . ' (anonymous user)'; $subject = str_replace('$PAGEEDITOR', 'anonymous user '. $name, $subject); - - $keys['$PAGEEDITOR_RAWURL'] = $anonUrl; - $keys['%24PAGEEDITOR_RAWURL'] = $anonUrl; - $keys['%24PAGEEDITORE'] = $anon; - $keys['$PAGEEDITORE'] = $anon; - $keys['$PAGEEDITOR'] = 'anonymous user ' . $name; + $keys['$PAGEEDITOR'] = 'anonymous user ' . $name; + $keys['$PAGEEDITOR_EMAIL'] = wfMsgForContent( 'noemailtitle' ); } else { $subject = str_replace('$PAGEEDITOR', $name, $subject); - $keys['$PAGEEDITOR_RAWURL'] = wfUrlencode( $name ); - $keys['%24PAGEEDITOR_RAWURL'] = wfUrlencode( $name ); - $keys['%24PAGEEDITORE'] = $pageeditorUser->getTitleKey(); - $keys['$PAGEEDITORE'] = $pageeditorUser->getTitleKey(); $keys['$PAGEEDITOR'] = $name; + $emailPage = SpecialPage::getSafeTitleFor( 'Emailuser', $name ); + $keys['$PAGEEDITOR_EMAIL'] = $emailPage->getFullUrl(); } + $userPage = $wgUser->getUserPage(); + $keys['$PAGEEDITOR_WIKI'] = $userPage->getFullUrl(); $body = strtr( $body, $keys ); - + $body = wordwrap( $body, 72 ); + # now save this as the constant user-independent part of the message - $this->to = $to; $this->from = $from; $this->replyto = $replyto; - $this->subject = wfQuotedprintable($subject); + $this->subject = $subject; $this->body = $body; - return $this; } - + /** * Does the per-user customizations to a notification e-mail (name, * timestamp in proper timezone, etc) and sends it out. @@ -375,30 +406,27 @@ class EmailNotification { * * @param User $watchingUser * @param object $mail - * @param Article $article * @return bool - * @access private + * @private */ - function composeAndSendPersonalisedMail( $watchingUser, $mail, $article ) { + function composeAndSendPersonalisedMail( $watchingUser ) { global $wgLang; - - $to = $watchingUser->getName() . ' <' . $watchingUser->getEmail() . '>'; - $body = str_replace( '$WATCHINGUSERNAME', $watchingUser->getName() , $mail->body ); - $body = str_replace( '$WATCHINGUSEREMAILADDR', $watchingUser->getEmail(), $body ); - + // From the PHP manual: + // Note: The to parameter cannot be an address in the form of "Something ". + // The mail command will not parse this properly while talking with the MTA. + $to = new MailAddress( $watchingUser ); + $body = str_replace( '$WATCHINGUSERNAME', $watchingUser->getName() , $this->body ); + $timecorrection = $watchingUser->getOption( 'timecorrection' ); - if( !$timecorrection ) { - # fail safe - I prefer it. TomGries - $timecorrection = '00:00'; - } + # $PAGEEDITDATE is the time and date of the page change # expressed in terms of individual local time of the notification # recipient, i.e. watching user $body = str_replace('$PAGEEDITDATE', - $wgLang->timeanddate( $article->mTimestamp, true, false, $timecorrection ), + $wgLang->timeanddate( $this->timestamp, true, false, $timecorrection ), $body); - - $error = userMailer( $to, $mail->from, $mail->subject, $body, $mail->replyto ); + + $error = userMailer( $to, $this->from, $this->subject, $body, $this->replyto ); return ($error == ''); }