From a2c2cb5687f98fc9f796063f1f3ef66cf091cfc8 Mon Sep 17 00:00:00 2001 From: Alexandre Emsenhuber Date: Sat, 15 Oct 2011 09:32:03 +0000 Subject: [PATCH] * Added Language::userDate(), Language::userTime() and Language::userTimeAndDate() as new versions of respectively Language::date(), Language::time() and Language::timeanddate(), which take a User object in the second parameter to get time correction and format instead of having to do this when calling the methods and not wanting to user $wgUser's parameters. * Moved Language::userAdjust() near other related function * Updated ENotif stuff to use that functions so that the date format is not taken from the sending user but the receiver * Removed $PAGEEDITDATEANDTIME parameter, unsed and not present in impersonal notification * Also fixed the debug line in UserMailer::send() --- includes/UserMailer.php | 39 +++--- languages/Language.php | 259 ++++++++++++++++++++++++++++------------ 2 files changed, 199 insertions(+), 99 deletions(-) diff --git a/includes/UserMailer.php b/includes/UserMailer.php index 649fa20a7a..ad713ef55d 100644 --- a/includes/UserMailer.php +++ b/includes/UserMailer.php @@ -158,7 +158,7 @@ class UserMailer { global $wgEnotifMaxRecips, $wgAdditionalMailParams; $emails = ''; - wfDebug( __METHOD__ . ': sending mail to ' . implode( ',', array( $to->toString() ) ) . "\n" ); + wfDebug( __METHOD__ . ': sending mail to ' . is_array( $to ) ? implode( ', ', $to ) : $to . "\n" ); $headers['From'] = $from->toString(); $headers['Return-Path'] = $from->toString(); @@ -571,8 +571,14 @@ class EmailNotification { $keys = array(); if ( $this->oldid ) { - $difflink = $this->title->getCanonicalUrl( 'diff=0&oldid=' . $this->oldid ); - $keys['$NEWPAGE'] = wfMsgForContent( 'enotif_lastvisited', $difflink ); + if ( $wgEnotifImpersonal ) { + // For impersonal mail, show a diff link to the last revision. + $keys['$NEWPAGE'] = wfMsgForContent( 'enotif_lastdiff', + $this->title->getCanonicalUrl( 'diff=next&oldid=' . $this->oldid ) ); + } else { + $keys['$NEWPAGE'] = wfMsgForContent( 'enotif_lastvisited', + $this->title->getCanonicalUrl( 'diff=0&oldid=' . $this->oldid ) ); + } $keys['$OLDID'] = $this->oldid; $keys['$CHANGEDORCREATED'] = wfMsgForContent( 'changed' ); } else { @@ -582,15 +588,6 @@ class EmailNotification { $keys['$CHANGEDORCREATED'] = wfMsgForContent( 'created' ); } - if ( $wgEnotifImpersonal && $this->oldid ) { - /** - * For impersonal mail, show a diff link to the last - * revision. - */ - $keys['$NEWPAGE'] = wfMsgForContent( 'enotif_lastdiff', - $this->title->getCanonicalUrl( "oldid={$this->oldid}&diff=next" ) ); - } - $body = strtr( $body, $keys ); $pagetitle = $this->title->getPrefixedText(); $keys['$PAGETITLE'] = $pagetitle; @@ -691,22 +688,18 @@ class EmailNotification { // 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 ); - $name = $wgEnotifUseRealName ? $watchingUser->getRealName() : $watchingUser->getName(); - $body = str_replace( '$WATCHINGUSERNAME', $name, $this->body ); - - $timecorrection = $watchingUser->getOption( 'timecorrection' ); # $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( - array( '$PAGEEDITDATEANDTIME', + array( '$WATCHINGUSERNAME', '$PAGEEDITDATE', '$PAGEEDITTIME' ), - array( $wgContLang->timeanddate( $this->timestamp, true, false, $timecorrection ), - $wgContLang->date( $this->timestamp, true, false, $timecorrection ), - $wgContLang->time( $this->timestamp, true, false, $timecorrection ) ), - $body ); + array( $wgEnotifUseRealName ? $watchingUser->getRealName() : $watchingUser->getName(), + $wgContLang->userDate( $this->timestamp, $watchingUser ), + $wgContLang->userTime( $this->timestamp, $watchingUser ) ), + $this->body ); return UserMailer::send( $to, $this->from, $this->subject, $body, $this->replyto ); } @@ -726,8 +719,8 @@ class EmailNotification { '$PAGEEDITDATE', '$PAGEEDITTIME' ), array( wfMsgForContent( 'enotif_impersonal_salutation' ), - $wgContLang->date( $this->timestamp, true, false, false ), - $wgContLang->time( $this->timestamp, true, false, false ) ), + $wgContLang->date( $this->timestamp, false, false ), + $wgContLang->time( $this->timestamp, false, false ) ), $this->body ); return UserMailer::send( $addresses, $this->from, $this->subject, $body, $this->replyto ); diff --git a/languages/Language.php b/languages/Language.php index 78d35032da..6059e28c11 100644 --- a/languages/Language.php +++ b/languages/Language.php @@ -805,82 +805,6 @@ class Language { return $this->getMessageFromDB( self::$mHijriCalendarMonthMsgs[$key - 1] ); } - /** - * Used by date() and time() to adjust the time output. - * - * @param $ts Int the time in date('YmdHis') format - * @param $tz Mixed: adjust the time by this amount (default false, mean we - * get user timecorrection setting) - * @return int - */ - function userAdjust( $ts, $tz = false ) { - global $wgUser, $wgLocalTZoffset; - - if ( $tz === false ) { - $tz = $wgUser->getOption( 'timecorrection' ); - } - - $data = explode( '|', $tz, 3 ); - - if ( $data[0] == 'ZoneInfo' ) { - wfSuppressWarnings(); - $userTZ = timezone_open( $data[2] ); - wfRestoreWarnings(); - if ( $userTZ !== false ) { - $date = date_create( $ts, timezone_open( 'UTC' ) ); - date_timezone_set( $date, $userTZ ); - $date = date_format( $date, 'YmdHis' ); - return $date; - } - # Unrecognized timezone, default to 'Offset' with the stored offset. - $data[0] = 'Offset'; - } - - $minDiff = 0; - if ( $data[0] == 'System' || $tz == '' ) { - #  Global offset in minutes. - if ( isset( $wgLocalTZoffset ) ) { - $minDiff = $wgLocalTZoffset; - } - } elseif ( $data[0] == 'Offset' ) { - $minDiff = intval( $data[1] ); - } else { - $data = explode( ':', $tz ); - if ( count( $data ) == 2 ) { - $data[0] = intval( $data[0] ); - $data[1] = intval( $data[1] ); - $minDiff = abs( $data[0] ) * 60 + $data[1]; - if ( $data[0] < 0 ) { - $minDiff = -$minDiff; - } - } else { - $minDiff = intval( $data[0] ) * 60; - } - } - - # No difference ? Return time unchanged - if ( 0 == $minDiff ) { - return $ts; - } - - wfSuppressWarnings(); // E_STRICT system time bitching - # Generate an adjusted date; take advantage of the fact that mktime - # will normalize out-of-range values so we don't have to split $minDiff - # into hours and minutes. - $t = mktime( ( - (int)substr( $ts, 8, 2 ) ), # Hours - (int)substr( $ts, 10, 2 ) + $minDiff, # Minutes - (int)substr( $ts, 12, 2 ), # Seconds - (int)substr( $ts, 4, 2 ), # Month - (int)substr( $ts, 6, 2 ), # Day - (int)substr( $ts, 0, 4 ) ); # Year - - $date = date( 'YmdHis', $t ); - wfRestoreWarnings(); - - return $date; - } - /** * This is a workalike of PHP's date() function, but with better * internationalisation, a reduced set of format characters, and a better @@ -1719,6 +1643,82 @@ class Language { return $str; } + /** + * Used by date() and time() to adjust the time output. + * + * @param $ts Int the time in date('YmdHis') format + * @param $tz Mixed: adjust the time by this amount (default false, mean we + * get user timecorrection setting) + * @return int + */ + function userAdjust( $ts, $tz = false ) { + global $wgUser, $wgLocalTZoffset; + + if ( $tz === false ) { + $tz = $wgUser->getOption( 'timecorrection' ); + } + + $data = explode( '|', $tz, 3 ); + + if ( $data[0] == 'ZoneInfo' ) { + wfSuppressWarnings(); + $userTZ = timezone_open( $data[2] ); + wfRestoreWarnings(); + if ( $userTZ !== false ) { + $date = date_create( $ts, timezone_open( 'UTC' ) ); + date_timezone_set( $date, $userTZ ); + $date = date_format( $date, 'YmdHis' ); + return $date; + } + # Unrecognized timezone, default to 'Offset' with the stored offset. + $data[0] = 'Offset'; + } + + $minDiff = 0; + if ( $data[0] == 'System' || $tz == '' ) { + #  Global offset in minutes. + if ( isset( $wgLocalTZoffset ) ) { + $minDiff = $wgLocalTZoffset; + } + } elseif ( $data[0] == 'Offset' ) { + $minDiff = intval( $data[1] ); + } else { + $data = explode( ':', $tz ); + if ( count( $data ) == 2 ) { + $data[0] = intval( $data[0] ); + $data[1] = intval( $data[1] ); + $minDiff = abs( $data[0] ) * 60 + $data[1]; + if ( $data[0] < 0 ) { + $minDiff = -$minDiff; + } + } else { + $minDiff = intval( $data[0] ) * 60; + } + } + + # No difference ? Return time unchanged + if ( 0 == $minDiff ) { + return $ts; + } + + wfSuppressWarnings(); // E_STRICT system time bitching + # Generate an adjusted date; take advantage of the fact that mktime + # will normalize out-of-range values so we don't have to split $minDiff + # into hours and minutes. + $t = mktime( ( + (int)substr( $ts, 8, 2 ) ), # Hours + (int)substr( $ts, 10, 2 ) + $minDiff, # Minutes + (int)substr( $ts, 12, 2 ), # Seconds + (int)substr( $ts, 4, 2 ), # Month + (int)substr( $ts, 6, 2 ), # Day + (int)substr( $ts, 0, 4 ) ); # Year + + $date = date( 'YmdHis', $t ); + wfRestoreWarnings(); + + return $date; + } + /** * This is meant to be used by time(), date(), and timeanddate() to get * the date preference they're supposed to use, it should be used in @@ -1839,6 +1839,113 @@ class Language { return $this->sprintfDate( $df, $ts ); } + /** + * Internal helper function for userDate(), userTime() and userTimeAndDate() + * + * @param $type String: can be 'date', 'time' or 'both' + * @param $ts Mixed: the time format which needs to be turned into a + * date('YmdHis') format with wfTimestamp(TS_MW,$ts) + * @param $user User object used to get preferences for timezone and format + * @param $options Array, can contain the following keys: + * - 'timecorrection': time correction, can have the following values: + * - true: use user's preference + * - false: don't use time correction + * - integer: value of time correction in minutes + * - 'format': format to use, can have the following values: + * - true: use user's preference + * - false: use default preference + * - string: format to use + * @return String + */ + private function internalUserTimeAndDate( $type, $ts, User $user, array $options ) { + $ts = wfTimestamp( TS_MW, $ts ); + $options += array( 'timecorrection' => true, 'format' => true ); + if ( $options['timecorrection'] !== false ) { + if ( $options['timecorrection'] === true ) { + $offset = $user->getOption( 'timecorrection' ); + } else { + $offset = $options['timecorrection']; + } + $ts = $this->userAdjust( $ts, $offset ); + } + if ( $options['format'] === true ) { + $format = $user->getDatePreference(); + } else { + $format = $options['format']; + } + $df = $this->getDateFormatString( $type, $this->dateFormat( $format ) ); + return $this->sprintfDate( $df, $ts ); + } + + /** + * Get the formatted date for the given timestamp and formatted for + * the given user. + * + * @param $type String: can be 'date', 'time' or 'both' + * @param $ts Mixed: the time format which needs to be turned into a + * date('YmdHis') format with wfTimestamp(TS_MW,$ts) + * @param $user User object used to get preferences for timezone and format + * @param $options Array, can contain the following keys: + * - 'timecorrection': time correction, can have the following values: + * - true: use user's preference + * - false: don't use time correction + * - integer: value of time correction in minutes + * - 'format': format to use, can have the following values: + * - true: use user's preference + * - false: use default preference + * - string: format to use + * @return String + */ + public function userDate( $ts, User $user, array $options = array() ) { + return $this->internalUserTimeAndDate( 'date', $ts, $user, $options ); + } + + /** + * Get the formatted time for the given timestamp and formatted for + * the given user. + * + * @param $type String: can be 'date', 'time' or 'both' + * @param $ts Mixed: the time format which needs to be turned into a + * date('YmdHis') format with wfTimestamp(TS_MW,$ts) + * @param $user User object used to get preferences for timezone and format + * @param $options Array, can contain the following keys: + * - 'timecorrection': time correction, can have the following values: + * - true: use user's preference + * - false: don't use time correction + * - integer: value of time correction in minutes + * - 'format': format to use, can have the following values: + * - true: use user's preference + * - false: use default preference + * - string: format to use + * @return String + */ + public function userTime( $ts, User $user, array $options = array() ) { + return $this->internalUserTimeAndDate( 'time', $ts, $user, $options ); + } + + /** + * Get the formatted date and time for the given timestamp and formatted for + * the given user. + * + * @param $type String: can be 'date', 'time' or 'both' + * @param $ts Mixed: the time format which needs to be turned into a + * date('YmdHis') format with wfTimestamp(TS_MW,$ts) + * @param $user User object used to get preferences for timezone and format + * @param $options Array, can contain the following keys: + * - 'timecorrection': time correction, can have the following values: + * - true: use user's preference + * - false: don't use time correction + * - integer: value of time correction in minutes + * - 'format': format to use, can have the following values: + * - true: use user's preference + * - false: use default preference + * - string: format to use + * @return String + */ + public function userTimeAndDate( $ts, User $user, array $options = array() ) { + return $this->internalUserTimeAndDate( 'both', $ts, $user, $options ); + } + /** * @param $key string * @return array|null -- 2.20.1