? cvs-update-logfile ? cvs.diff ? rel15+enec316.tgz ? maintenance/archives/patch-create-user_newtalk.sql ? maintenance/archives/patch-email-notification-fornewpages.sql Index: RELEASE-NOTES =================================================================== RCS file: /cvsroot/wikipedia/phase3/RELEASE-NOTES,v retrieving revision 1.58 diff -u -b -r1.58 RELEASE-NOTES --- RELEASE-NOTES 27 Apr 2005 21:17:29 -0000 1.58 +++ RELEASE-NOTES 28 Apr 2005 20:10:21 -0000 @@ -35,38 +35,121 @@ * stuff -== Version Enotif+Eauthent EN+EA v2.00/CVS, 14.12.2004 == -written by Thomas Gries, Berlin and Markus Arndt, Munich +***** THIS IS ENOTIF/EAUTHENT ******* + +ENotif (EN) + EAuthent (EA) V 3.17 for REL1_4 (1.4.2) +(C) T. Gries 28.04.2005 Executive summary for the impatient reader: -Enotif adds e-mail notification to MediaWiki and sends e-mails -to watching users when a watch-listed page or user_talk page is changed -http://bugzilla.wikipedia.org/show_bug.cgi?id=454 -Visit the complete documentation on http://meta.wikipedia.org/Enotif - -Eauthent is a mechanism to use a temporary one-time password cycle -to check whether the email address a user has entered is a valid one. -http://bugzilla.wikipedia.org/show_bug.cgi?id=866 -Visit the complete documentation on http://meta.wikipedia.org/Eauthent +* ENotif adds e-mail notification to MediaWiki and + sends e-mails to watching users when a + + - watch-listed page or + - user_talk page is changed or + - a new page is created + + http://bugzilla.wikipedia.org/show_bug.cgi?id=454 + Visit the complete documentation on http://meta.wikipedia.org/Enotif + +* EConfirm is a mechanism to sned a link to an unconfirmed e-mail + address. The user needs to follow this link to confirm the e-mail + address in the settings, the confirmation status always being + shown there. -The current patch has only been checked for (see DefaultSettings.php): +* Dozens of other bugzillas implemented, + See http://meta.wikipedia.org/Enotif for the whole list. -- php mail() + The current patch has only been checked for (see DefaultSettings.php): + + - php mail() ( = not using PEAR:Mail() module --- I do not know anyone who uses that) $wgSMTP = false; -- MySQL database + + - MySQL database ( = not using PostgreSQL --- I do not know anyone who uses that) $wgDBtype = "mysql"; $wgSearchType = "MyISAM"; -- STILL TODO: - NEW (newpageletter) and CORR (minoreditletter) markers needs - corresponding "spacers" - -- table user_newtalk dropped; changes on usertalk pages and their - notifications are now fully handled via existing table watchlist - The user interface and behavious is unchanged to previous version. +# Still to-do: +# We must not send new page notification to a user, +# who already is watching this page in advance (you have add pages +# to your watchlist before they exist) + +v3.17 +* bug fixed that address was always confirmed immediately. + +v3.11 +* bug in Emailuser.php fixed, must use Database::TimestampNULL() + +v3.10 +* I18N: ENotif text messages translated for German LanguageDE.php + +v3.09 +* bug fix: in SpecialPreferences, check settings before storing in db + (preventing form tampering) + +v3.08 +* new feature: e-mail notifications are sent when a new page is created. + user option; a switch in DefaultSettings determines, whether the option + is enabled for all or only enabled for Bureaucrats, Developers, Sysops. + A database schema change is required: + new field user_emailnotificationfornewpages is added to table user + run yourwiki/maintenance/> php update.php + +v3.07 +* When moving a page (which is watched), the existing watch properties + are taken into consideration for determining the watch properties + of the target page: + the subject and/or talk target pages are watched depending + on the old watchlist entries regardless of the check box status + "move talk page as well" ! + +v3.06 +* Labels "(last)" changed to "(prev)" +* New meaning of "(last)" is "difference between this and last seen + revision of this page" + +v3.05 for REL1_4 +* optimised program design + all ENotif calls are moved to module RecentChange.php + no tricks -- straightforward +* Writing to a user_talk or a USER page both triggers the + "You have new messages" marker and - if enabled - sending an ENotif. + This feature can be disabled globally. +* Both pages are automatically added to the watchlist of the user, + if someone leaves a message on one +* When adding a watch to a page, the talk_page is also watched and + vice versa (standard behaviour of mediawiki is unchanged), but + new watchlist management in Special:Watchlist allows to remove + watched pages and their talk pages independently. + This feature can be disabled globally (compatibility) +* The "You have new messages" marker has got direct links to the + _difference_ view between current and last seen revision +* database schema has changed; + run php update.php or make a fresh installation + The datatype for EN and EA timestamps has been changed from + varchar(14) to datetime +* removed EA minor bug in SpecialPreferences: + EA timestamp are now invalidated when user clears her password +* email addresses of sysops, bureaucrats and developers are + automatically authenticated as they are entered in user preferences + (can be disabled, so that every address must be authenticated) + +Other features: + +* added (lvrd) links: + link for difference between current and last-visited revision + in recent-changes view +* introducing tooltips for (diff) (hist) (cur) (last) and + for updatedmarker +* All texts can be disabled by clearing the strings cur_tooltiptext etc. + in LanguageXX.php +* User option to suppress the listing of older revisions of pages in + recent changes view: show only the current revisions of pages + +== Version Enotif+Eauthent EN+EA v2.00/CVS, 14.12.2004 == + - updaters.inc for compatibility with older mediawiki tables: the conversion script converts existing user_newtalk entries watchlist table entries Index: config/index.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/config/index.php,v retrieving revision 1.114 diff -u -b -r1.114 index.php --- config/index.php 26 Apr 2005 20:01:28 -0000 1.114 +++ config/index.php 28 Apr 2005 20:10:21 -0000 @@ -423,10 +423,10 @@ } /* default values for installation */ -$conf->Email =importRequest("Email", "email_enabled"); -$conf->Emailuser=importRequest("Emailuser", "emailuser_enabled"); -$conf->Enotif =importRequest("Enotif", "enotif_allpages"); -$conf->Eauthent =importRequest("Eauthent", "eauthent_enabled"); +$conf->Email = importRequest("Email", "email_enabled"); +$conf->Emailuser= importRequest("Emailuser", "emailuser_enabled"); +$conf->Enotif = importRequest("Enotif", "enotif_allpages"); +$conf->Econfirm = importRequest("Econfirm", "econfirm_enabled"); if( $conf->posted && ( 0 == count( $errs ) ) ) { do { /* So we can 'continue' to end prematurely */ @@ -800,7 +800,7 @@ use Turck shared memory if the wiki will be running on a single Apache server. -

E-mail, e-mail notification and authentification setup

+

E-mail, e-mail notification and confirmation setup

@@ -852,24 +852,23 @@
- +
Select one:
    -
  • -
  • +
  • +

- E-mail address authentication uses a scheme to authenticate e-mail addresses of the users. The user who initially enters or who changes his/her stored e-mail address - gets a one-time temporary password mailed to that address. The user can use the original password as long as wanted, however, the stored e-mail address - is only authenticated at the moment when the user logs in with the one-time temporary password.

+ E-mail address confirmation uses a scheme to confirm e-mail addresses of the users. The user who initially enters or changes his/her stored e-mail address + gets a link with a token mailed to that address. The stored e-mail address is only confirmed at the moment the user comes back to the wiki via the link.

-

The e-mail address stays authenticated as long as the user does not change it; the time of authentication is indicated +

The e-mail address stays confirmed as long as the user does not change it; the confirmation status and time is always indicated on the user preference page.

-

If the option is enabled, only authenticated e-mail addresses can receive EmailUser mails and/or +

If the option is enabled, only confirmed e-mail addresses can receive EmailUser mails and/or e-mail notification mails.

@@ -1007,7 +1006,7 @@ if ( $conf->Email == 'email_enabled' ) { $enableemail = 'true'; $enableuseremail = ( $conf->Emailuser == 'emailuser_enabled' ) ? 'true' : 'false' ; - $eauthent = ( $conf->Eauthent == 'eauthent_enabled' ) ? 'true' : 'false' ; + $econfirm = ( $conf->Econfirm == 'econfirm_enabled' ) ? 'true' : 'false' ; switch ( $conf->Enotif ) { case 'enotif_usertalk': $enotifusertalk = 'true'; @@ -1024,7 +1023,7 @@ } else { $enableuseremail = 'false'; $enableemail = 'false'; - $eauthent = 'false'; + $econfirm = 'false'; $enotifusertalk = 'false'; $enotifwatchlist = 'false'; } @@ -1094,13 +1093,13 @@ \$wgPasswordSender = \"{$slconf['PasswordSender']}\"; ## For a detailed description of the following switches see -## http://meta.wikimedia.org/Enotif and http://meta.wikimedia.org/Eauthent +## http://meta.wikimedia.org/Enotif ## There are many more options for fine tuning available see ## /includes/DefaultSettings.php ## UPO means: this is also a user preference option \$wgEmailNotificationForUserTalkPages = $enotifusertalk; # UPO \$wgEmailNotificationForWatchlistPages = $enotifwatchlist; # UPO -\$wgEmailAuthentication = $eauthent; +\$wgEmailConfirmation = $econfirm; \$wgDBserver = \"{$slconf['DBserver']}\"; \$wgDBname = \"{$slconf['DBname']}\"; Index: includes/Article.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/Article.php,v retrieving revision 1.316 diff -u -b -r1.316 Article.php --- includes/Article.php 26 Apr 2005 09:52:10 -0000 1.316 +++ includes/Article.php 28 Apr 2005 20:10:23 -0000 @@ -100,7 +100,7 @@ $this->loadContent( $noredir ); # check if we're displaying a [[User talk:x.x.x.x]] anonymous talk page if ( $this->mTitle->getNamespace() == NS_USER_TALK && - preg_match('/^\d{1,3}\.\d{1,3}.\d{1,3}\.\d{1,3}$/',$this->mTitle->getText()) && + User::isIP($this->mTitle->getText()) && $action=='view' ) { wfProfileOut( $fname ); @@ -627,7 +627,7 @@ function view() { global $wgUser, $wgOut, $wgRequest, $wgOnlySysopsCanPatrol, $wgLang; global $wgLinkCache, $IP, $wgEnableParserCache, $wgStylePath, $wgUseRCPatrol; - global $wgEnotif, $wgParser; + global $wgParser; $sk = $wgUser->getSkin(); $fname = 'Article::view'; @@ -927,9 +927,6 @@ $this->updateRevisionOn( $dbw, $revision, 0 ); Article::onArticleCreate( $this->mTitle ); - if(!$suppressRC) { - RecentChange::notifyNew( $now, $this->mTitle, $isminor, $wgUser, $summary ); - } if ($watchthis) { if(!$this->mTitle->userIsWatching()) $this->watch(); @@ -948,10 +945,17 @@ $fname ); # standard deferred updates - $this->editUpdates( $text, $summary, $isminor, $now ); + $this->editUpdates( $text ); + + # Is important to call RecentChange::notifyNew _after_ editUpdates + # because a user_newtalk flag and addwatch might be committed in editUpdates + # which triggers the sending of an Enotif in RecentChange::notifyNew just right now + if(!$suppressRC) { + RecentChange::notifyNew( $now, $this->mTitle, $isminor, $wgUser, $summary ); + } $oldid = 0; # new article - $this->showArticle( $text, wfMsg( 'newarticle' ), false, $isminor, $now, $summary, $oldid ); + $this->showArticle( $text, wfMsg( 'newarticle' ), false ); } /** @@ -1113,6 +1117,7 @@ $lastRevision = 0; if ( 0 != strcmp( $text, $oldtext ) ) { + $empty = false; $this->mCountAdjustment = $this->isCountable( $text ) - $this->isCountable( $oldtext ); $now = wfTimestampNow(); @@ -1135,12 +1140,12 @@ /* Belated edit conflict! Run away!! */ $good = false; } else { - # Update recentchanges and purge cache and whatnot + # Update recentchanges (moved some lines below) and purge cache and whatnot $bot = (int)($wgUser->isBot() || $forceBot); - RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $wgUser, $summary, - $lastRevision, $this->getTimestamp(), $bot ); Article::onArticleEdit( $this->mTitle ); } + } else { + $empty = true; } if( !$wgDBtransactions ) { @@ -1156,8 +1161,16 @@ } } # standard deferred updates - $this->editUpdates( $text, $summary, $minor, $now ); + $this->editUpdates( $text ); + if (!$empty) { + # moved from above to make sure editUpdates were performed: + # Is important to call RecentChange::notifyEdit _after_ editUpdates + # because a user_newtalk flag and addwatch might be committed in editUpdates + # which triggers the sending of an Enotif in RecentChange::notifyEdit just right now + RecentChange::notifyEdit( $now, $this->mTitle, $isminor, $wgUser, $summary, + $lastRevision, $this->getTimestamp(), $bot ); + } $urls = array(); # Template namespace @@ -1179,7 +1192,7 @@ array_push( $wgPostCommitUpdateList, $u ); } - $this->showArticle( $text, wfMsg( 'updated' ), $sectionanchor, $isminor, $now, $summary, $lastRevision ); + $this->showArticle( $text, wfMsg( 'updated' ), $sectionanchor ); } return $good; } @@ -1188,8 +1201,8 @@ * After we've either updated or inserted the article, update * the link tables and redirect to the new page. */ - function showArticle( $text, $subtitle , $sectionanchor = '', $me2, $now, $summary, $oldid ) { - global $wgOut, $wgUser, $wgLinkCache, $wgEnotif; + function showArticle( $text, $subtitle , $sectionanchor = '' ) { + global $wgOut, $wgUser, $wgLinkCache; $wgLinkCache = new LinkCache(); # Select for update @@ -1212,12 +1225,6 @@ $r = ''; $wgOut->redirect( $this->mTitle->getFullURL( $r ).$sectionanchor ); - # this call would better fit into RecentChange::notifyEdit and RecentChange::notifyNew . - # this will be improved later (to-do) - - include_once( "UserMailer.php" ); - $wgEnotif = new EmailNotification (); - $wgEnotif->NotifyOnPageChange( $wgUser->getID(), $this->mTitle->getDBkey(), $this->mTitle->getNamespace(),$now, $summary, $me2, $oldid ); } /** @@ -1913,14 +1920,33 @@ # talk page global $wgUser; - if ($this->mTitle->getNamespace() == NS_USER_TALK && - $this->mTitle->getText() == $wgUser->getName()) { - require_once( 'UserTalkUpdate.php' ); - $u = new UserTalkUpdate( 0, $this->mTitle->getNamespace(), $this->mTitle->getDBkey(), false, false, false ); + global $wgShowNewtalkForUserOrUserTalkPage; + + if ( $wgShowNewtalkForUserOrUserTalkPage ) { + # We need to check both the user_talk and user page for pending updates + # If nothing is pending, then we clear the newtalk flag + + if ( $this->mTitle->getText() == $wgUser->getName() ) { + if ( ( ($this->mTitle->getNamespace() == NS_USER_TALK) && + (!$wgUser->checkNotificationPendingForArticleOrTalk($this->mTitle, NS_USER, $lvr )) ) + || + ( ($this->mTitle->getNamespace() == NS_USER) && + (!$wgUser->checkNotificationPendingForArticleOrTalk($this->mTitle, NS_USER_TALK, $lvr)) ) ) { + $wgUser->setNewtalk(0); + $wgUser->saveNewtalk(); + } + } } else { - $wgUser->clearNotification( $this->mTitle ); + if ($this->mTitle->getNamespace() == NS_USER_TALK && + $this->mTitle->getText() == $wgUser->getName()) + { + $wgUser->setNewtalk(0); + $wgUser->saveNewtalk(); + } } + $wgUser->clearNotification( $this->mTitle ); + } /** @@ -1929,7 +1955,7 @@ * @private * @param string $text */ - function editUpdates( $text, $summary, $minoredit, $timestamp_of_pagechange) { + function editUpdates( $text ) { global $wgDeferredUpdateList, $wgDBname, $wgMemc; global $wgMessageCache, $wgUser; @@ -1957,13 +1983,20 @@ $u = new SearchUpdate( $id, $title, $text ); array_push( $wgDeferredUpdateList, $u ); - # If this is another user's talk page, + # If this is another user's page or talk page, + # save a newtalk notification for them and # create a watchlist entry for this page - if ($this->mTitle->getNamespace() == NS_USER_TALK && - $shortTitle != $wgUser->getName()) { - require_once( 'UserTalkUpdate.php' ); - $u = new UserTalkUpdate( 1, $this->mTitle->getNamespace(), $shortTitle, $summary, $minoredit, $timestamp_of_pagechange); + global $wgShowNewtalkForUserOrUserTalkPage; + if ( ( ($this->mTitle->getNamespace() == NS_USER_TALK) || + ($wgShowNewtalkForUserOrUserTalkPage && ($this->mTitle->getNamespace() == NS_USER) ) ) && + $shortTitle != $wgUser->getName() ) { + $other = User::newFromName($shortTitle); + if (!$other->getNewtalk()) { + $other->addWatch( $this->mTitle ); + $other->setNewtalk(1); + $other->saveNewtalk(); + } } if ( $this->mTitle->getNamespace() == NS_MEDIAWIKI ) { Index: includes/ChangesList.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/ChangesList.php,v retrieving revision 1.15 diff -u -b -r1.15 ChangesList.php --- includes/ChangesList.php 24 Apr 2005 15:43:49 -0000 1.15 +++ includes/ChangesList.php 28 Apr 2005 20:10:23 -0000 @@ -84,21 +84,30 @@ $r .= $link ; if ($rcObj->notificationtimestamp) { - $r .= wfMsg( 'updatedmarker' ); + $r .= $this->skin->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'updatedmarker' ), + "diff=0&oldid={$rcObj->lastvisitedrevision}", '', '', '', wfMsg( 'updatedmarker_tooltiptext' ) ); } # Diff $r .= ' (' ; $r .= $rcObj->difflink ; + if ($rcObj->lvrlink) { + $r .= "; ".$rcObj->lvrlink ; + } $r .= '; ' ; # Hist - $r .= $this->skin->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history' ); + $r .= $this->skin->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'hist' ), $curIdEq.'&action=history', '', '','', wfMsg( 'hist_tooltiptext' )); + # User/talk $r .= ') . . '.$rcObj->userlink ; $r .= $rcObj->usertalklink ; + if ($rcObj->numberofWatchingusers > 0) { + $r .= wfMsg('number_of_watching_users_RCview', $wgContLang->formatNum($rcObj->numberofWatchingusers)); + } + # Comment if ( $rc_type != RC_MOVE && $rc_type != RC_MOVE_OVER_REDIRECT ) { $r .= $this->skin->commentBlock( $rc_comment, $rcObj->getTitle() ); @@ -175,7 +184,8 @@ $r .= $link ; if ($block[0]->notificationtimestamp) { - $r .= wfMsg( 'updatedmarker' ); + $r .= $this->skin->makeKnownLinkObj( $rcObj->getTitle(), wfMsg( 'updatedmarker' ), + "diff=0&oldid={$rcObj->lastvisitedrevision}", '', '', '', wfMsg( 'updatedmarker_tooltiptext' ) ); } $curIdEq = 'curid=' . $block[0]->mAttribs['rc_cur_id']; @@ -189,6 +199,9 @@ # History $r .= $this->skin->makeKnownLinkObj( $block[0]->getTitle(), wfMsg( 'history' ), $curIdEq.'&action=history' ); + if ($block[0]->lvrlink) { + $r .= "; ".$block[0]->lvrlink; + } $r .= ')' ; } @@ -280,7 +293,8 @@ static $message; if( !isset( $message ) ) { - foreach( explode(' ', 'diff hist minoreditletter newpageletter blocklink' ) as $msg ) { + foreach( explode(' ', 'diff diff_tooltiptext hist hist_tooltiptext minoreditletter newpageletter blocklink undo '. + 'diff-to-lvr lvr diff-to-lvr_tooltiptext lvr_tooltiptext updatedmarker updatedmarker_tooltiptext ' ) as $msg ) { $message[$msg] = wfMsg( $msg ); } } @@ -309,7 +323,7 @@ # Diff $s .= '(' . $message['diff'] . ') ('; # Hist - $s .= $this->skin->makeKnownLinkObj( $rc->getMovedToTitle(), $message['hist'], 'action=history' ) . + $s .= $this->skin->makeKnownLinkObj( $rc->getMovedToTitle(), $message['hist'], 'action=history', '', '', '', $message['hist_tooltiptext'] ) . ') . . '; # "[[x]] moved to [[y]]" @@ -333,12 +347,24 @@ $rcidparam = ""; $diffLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['diff'], "{$curIdEq}&diff={$rc_this_oldid}&oldid={$rc_last_oldid}{$rcidparam}", - '', '', ' tabindex="'.$rc->counter.'"'); + '', '', ' tabindex="'.$rc->counter.'"', $message['diff_tooltiptext'] ); } - $s .= '('.$diffLink.') ('; + + if ( $watched && $rc->lastvisitedrevision ) { + if ( $rc_this_oldid == $rc->lastvisitedrevision ) { + $lvrLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['lvr'], + "diff={$rc_this_oldid}&oldid={$rc->lastvisitedrevision}", '','','', $message['lvr_tooltiptext']); + } else { + $lvrLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['diff-to-lvr'], + "diff={$rc_this_oldid}&oldid={$rc->lastvisitedrevision}",'','','', $message['diff-to-lvr_tooltiptext'] ); + } + } else { + $lvrLink = $message['diff-to-lvr']; + } + $s .= '('.$diffLink.') ('.$lvrLink.') ('; # History link - $s .= $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['hist'], $curIdEq.'&action=history' ); + $s .= $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['hist'], $curIdEq.'&action=history', '', '', '', $message['hist_tooltiptext'] ); $s .= ') . . '; # M, N and ! (minor, new and unpatrolled) @@ -357,7 +383,8 @@ } if ($rc->notificationtimestamp) { - $articleLink .= wfMsg( 'updatedmarker' ); + $articleLink .= $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['updatedmarker'], + "diff=0&oldid={$rc->lastvisitedrevision}",'','','', $message['updatedmarker_tooltiptext'] ); } $s .= ' '.$articleLink; @@ -424,7 +451,8 @@ static $message; if( !isset( $message ) ) { - foreach( explode(' ', 'cur diff hist minoreditletter newpageletter last blocklink' ) as $msg ) { + foreach( explode(' ', 'cur diff hist minoreditletter newpageletter last blocklink undo diff-to-lvr '. + 'diff-to-lvr_tooltiptext cur_tooltiptext diff_tooltiptext last_tooltiptext updatedmarker updatedmarker_tooltiptext ' ) as $msg ) { $message[$msg] = wfMsg( $msg ); } } @@ -478,6 +506,8 @@ $rc->timestamp = $time; $rc->notificationtimestamp = $baseRC->notificationtimestamp; $rc->numberofWatchingusers = $baseRC->numberofWatchingusers; + $rc->lastvisitedrevision = $baseRC->lastvisitedrevision; + # Make "cur" and "diff" links $titleObj = $rc->getTitle(); @@ -492,8 +522,8 @@ } else { $query = $curIdEq.'&diff=0&oldid='.$rc_this_oldid; $aprops = ' tabindex="'.$baseRC->counter.'"'; - $curLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['cur'], $query, '' ,'' , $aprops ); - $diffLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['diff'], $query . $rcIdQuery, '' ,'' , $aprops ); + $curLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['cur'], $query, '', '', $aprops, $message['cur_tooltiptext'] ); + $diffLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['diff'], $query . $rcIdQuery, '', '', $aprops, $message['diff_tooltiptext'] ); } # Make "last" link @@ -501,7 +531,7 @@ $lastLink = $message['last']; } else { $lastLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['last'], - $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid . $rcIdQuery ); + $curIdEq.'&diff='.$rc_this_oldid.'&oldid='.$rc_last_oldid . $rcIdQuery, '', '', '', $message['last_tooltiptext'] ); } # Make user link (or user contributions for unregistered users) @@ -513,7 +543,14 @@ $userPage =& Title::makeTitle( NS_USER, $rc_user_text ); $userLink = $this->skin->makeLinkObj( $userPage, $rc_user_text ); } + if ( $watched && $baseRC->lastvisitedrevision ) { + $lvrLink = $this->skin->makeKnownLinkObj( $rc->getTitle(), $message['diff-to-lvr'], + "{$curIdEq}&diff=0&oldid={$baseRC->lastvisitedrevision}" , '', '', '', $message['diff-to-lvr_tooltiptext'] ); + } else { + $lvrLink= '' ; + } + $rc->lvrlink = $lvrLink; $rc->userlink = $userLink; $rc->lastlink = $lastLink; $rc->curlink = $curLink; Index: includes/Database.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/Database.php,v retrieving revision 1.93 diff -u -b -r1.93 Database.php --- includes/Database.php 25 Apr 2005 18:38:16 -0000 1.93 +++ includes/Database.php 28 Apr 2005 20:10:24 -0000 @@ -1397,11 +1397,28 @@ } /** + * Returns a string to match in a database query for an undefined timestamp value + */ + function wl_notificationtimestampIsNULL() { + return 'wl_notificationtimestamp = 0'; # for VARCHAR(14) + + ## depending on your table definition it can also be + ## return 'wl_notificationtimestamp IS NULL'; # for DATETIME + + ## underlying problem: + ## + ## MySQL queries need different syntax when testing against NULL value + ## "SELECT ... foo=null;" is wrong, we need "SELECT ... foo IS NULL;" instead + } + + /** * Local database timestamp format or null */ function timestampOrNull( $ts = null ) { - if( is_null( $ts ) ) { - return null; + if( is_null( $ts ) || ($ts == 0) ) { + return 0; + ## depending on your table definition it can be + ## return null; } else { return $this->timestamp( $ts ); } Index: includes/DefaultSettings.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/DefaultSettings.php,v retrieving revision 1.293 diff -u -b -r1.293 DefaultSettings.php --- includes/DefaultSettings.php 25 Apr 2005 10:13:19 -0000 1.293 +++ includes/DefaultSettings.php 28 Apr 2005 20:10:25 -0000 @@ -16,7 +16,7 @@ if( defined( 'MEDIAWIKI' ) ) { /** MediaWiki version number */ -$wgVersion = '1.5pre-alpha'; +$wgVersion = '1.5pre-alpha + ENotif/EConfirm v3.17'; /** Name of the site. It must be changed in LocalSettings.php */ $wgSitename = 'MediaWiki'; @@ -621,24 +621,35 @@ // TODO move UPO to preferences probably ? # If set to true, users get a corresponding option in their preferences and can choose to enable or disable at their discretion # If set to false, the corresponding input form on the user preference page is suppressed -# It call this to be a "user-preferences-option (UPO)" -$wgEmailAuthentication = true; # UPO (if this is set to false, texts referring to authentication are suppressed) -$wgEmailNotificationForWatchlistPages = false; # UPO -$wgEmailNotificationForUserTalkPages = false; # UPO -$wgEmailNotificationRevealPageEditorAddress = false; # UPO; reply-to address may be filled with page editor's address (if user allowed this in the preferences) +# I call this a "user-preferences-option (UPO)" +$wgEmailConfirmation = true; # UPO (if this is set to false, texts referring to e-mail address confirmation are suppressed) +$wgEmailConfirmationRequiredForAll = false; # false means: Sysops, Bureaucrats and Developers don't need to confirm their email addresses +$wgEmailNotificationForWatchlistPages = true; # UPO +$wgEmailNotificationForUserTalkPages = true; # UPO +$wgEmailNotificationRevealPageEditorAddress = true; # UPO; reply-to address may be filled with page editor's address (if user allowed this in the preferences) $wgEmailNotificationForMinorEdits = true; # UPO; false: "minor edits" on pages do not trigger notification mails. # # Attention: _every_ change on a user_talk page trigger a notification mail (if the user is not yet notified) +$wgEmailNotificationForNewPages = true; # show the option +$wgEmailNotificationForNewPagesAllowedForAll = true; # false means: only Sysops, Bureaucrats and Developers see this option +# Show only the current revision of pages in recent changes +$wgRCShowCurrentRevisionOnly = true; # UPO /** Show watching users in recent changes, watchlist and page history views */ -$wgRCShowWatchingUsers = false; # UPO +$wgRCShowWatchingUsers = true; # UPO /** Show watching users in Page views */ -$wgPageShowWatchingUsers = false; +$wgPageShowWatchingUsers = true; /** * Show "Updated (since my last visit)" marker in RC view, watchlist and history * view for watched pages with new changes */ $wgShowUpdatedMarker = true; # UPO +/* whether on SpecialWatchlist the both pages are deleted together or not */ +$wgRemoveWatchedArticleAndTalkPageTogether = true; + +/* show the "You have new messages" for changes on both the user and usertalk page */ +$wgShowNewtalkForUserOrUserTalkPage = true; + $wgCookieExpiration = 2592000; # Squid-related settings Index: includes/GlobalFunctions.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/GlobalFunctions.php,v retrieving revision 1.165 diff -u -b -r1.165 GlobalFunctions.php --- includes/GlobalFunctions.php 25 Apr 2005 18:38:16 -0000 1.165 +++ includes/GlobalFunctions.php 28 Apr 2005 20:10:26 -0000 @@ -1064,8 +1064,10 @@ * @return string */ function wfTimestampOrNull( $outputtype = TS_UNIX, $ts = null ) { - if( is_null( $ts ) ) { - return null; + if( is_null( $ts ) || ($ts==0) ) { + ### return null; + ### underlying problem: see Database.php, it depends on your table definition + return 0; } else { return wfTimestamp( $outputtype, $ts ); } Index: includes/Linker.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/Linker.php,v retrieving revision 1.26 diff -u -b -r1.26 Linker.php --- includes/Linker.php 27 Apr 2005 07:48:12 -0000 1.26 +++ includes/Linker.php 28 Apr 2005 20:10:26 -0000 @@ -95,10 +95,10 @@ } /** @todo document */ - function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '') { + function makeKnownLink( $title, $text = '', $query = '', $trail = '', $prefix = '',$aprops = '', $hovertext = '') { $nt = Title::newFromText( $title ); if ($nt) { - return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail, $prefix , $aprops ); + return $this->makeKnownLinkObj( Title::newFromText( $title ), $text, $query, $trail, $prefix , $aprops, $hovertext ); } else { wfDebug( 'Invalid title passed to Skin::makeKnownLink(): "'.$title."\"\n" ); return $text == '' ? $title : $text; @@ -223,7 +223,7 @@ /** * Pass a title object, not a title string */ - function makeKnownLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '' ) { + function makeKnownLinkObj( $nt, $text = '', $query = '', $trail = '', $prefix = '' , $aprops = '', $hovertext= '' ) { global $wgOut, $wgTitle, $wgInputEncoding; $fname = 'Skin::makeKnownLinkObj'; @@ -252,7 +252,7 @@ if ( '' == $text ) { $text = htmlspecialchars( $nt->getPrefixedText() ); } - $style = $this->getInternalLinkAttributesObj( $nt, $text ); + $style = $this->getInternalLinkAttributesObj( $nt, $text, '', $hovertext ); list( $inside, $trail ) = Linker::splitTrail( $trail ); $r = "{$prefix}{$text}{$inside}{$trail}"; Index: includes/PageHistory.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/PageHistory.php,v retrieving revision 1.65 diff -u -b -r1.65 PageHistory.php --- includes/PageHistory.php 7 Apr 2005 06:59:53 -0000 1.65 +++ includes/PageHistory.php 28 Apr 2005 20:10:26 -0000 @@ -62,12 +62,24 @@ $title = $this->mTitle->getText(); $uid = $wgUser->getID(); $db =& wfGetDB( DB_SLAVE ); - if ($uid && $wgShowUpdatedMarker && $wgUser->getOption( 'showupdated' )) - $notificationtimestamp = $db->selectField( 'watchlist', - 'wl_notificationtimestamp', - array( 'wl_namespace' => $namespace, 'wl_title' => $this->mTitle->getDBkey(), 'wl_user' => $uid ), - $fname ); - else $notificationtimestamp = false; + if ($uid && $wgShowUpdatedMarker && $wgUser->getOption( 'showupdated' )) { + $s = $db->selectRow( 'watchlist', + array( 'wl_notificationtimestamp', + 'wl_lastvisitedrevision' + ), + array( 'wl_namespace' => $namespace, + 'wl_title' => $this->mTitle->getDBkey(), + 'wl_user' => $uid + ), $fname ); + if ( $s === false ) { + $notificationtimestamp = false; + } else { + $notificationtimestamp = $s->wl_notificationtimestamp; + $lastvisitedrevision = $s->wl_lastvisitedrevision; + } + } else { + $notificationtimestamp = false; + } $use_index = $db->useIndexClause( 'page_timestamp' ); $revision = $db->tableName( 'revision' ); @@ -138,7 +150,7 @@ foreach($pages as $i => $line) { $first = ($counter == 1 && $offset == 0); $next = isset( $pages[$i + 1] ) ? $pages[$i + 1 ] : null; - $s .= $this->historyLine( $line, $next, $counter, $notificationtimestamp, $first ); + $s .= $this->historyLine( $line, $next, $counter, $notificationtimestamp, $lastvisitedrevision, $first ); $counter++; } $s .= $this->endHistoryList( !$atend ); @@ -187,12 +199,13 @@ : ''; } - function historyLine( $row, $next, $counter = '', $notificationtimestamp = false, $latest = false ) { + function historyLine( $row, $next, $counter = '', $notificationtimestamp = false, $lastvisitedrevision = false, $latest = false ) { global $wgLang, $wgContLang; static $message; if( !isset( $message ) ) { - foreach( explode( ' ', 'cur last selectolderversionfordiff selectnewerversionfordiff minoreditletter' ) as $msg ) { + foreach( explode( ' ', 'cur last selectolderversionfordiff selectnewerversionfordiff minoreditletter '. + 'updatedmarker updatedmarker_tooltiptext last_tooltiptext cur_tooltiptext ' ) as $msg ) { $message[$msg] = wfMsg( $msg ); } } @@ -225,7 +238,8 @@ $s .= $this->mSkin->commentBlock( $row->rev_comment, $this->mTitle ); if ($notificationtimestamp && ($row->rev_timestamp >= $notificationtimestamp)) { - $s .= wfMsg( 'updatedmarker' ); + $s .= $this->mSkin->makeKnownLinkObj( $this->mTitle, $message['updatedmarker'], + "diff=0&oldid={$lastvisitedrevision}", '', '', '', $message['updatedmarker_tooltiptext'] ); } if( $row->rev_deleted ) { $s .= " " . htmlspecialchars( wfMsg( 'deletedrev' ) ); Index: includes/RecentChange.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/RecentChange.php,v retrieving revision 1.25 diff -u -b -r1.25 RecentChange.php --- includes/RecentChange.php 13 Mar 2005 07:19:13 -0000 1.25 +++ includes/RecentChange.php 28 Apr 2005 20:10:26 -0000 @@ -220,6 +220,10 @@ 'lastTimestamp' => $lastTimestamp ); $rc->save(); + + include_once( "UserMailer.php" ); + $wgEnotif = new EmailNotification (); + $wgEnotif->NotifyOnPageChangeOrNewpage( $timestamp, $title, $minor, $user, $comment, $oldId ); } # Makes an entry in the database corresponding to page creation @@ -261,6 +265,10 @@ 'lastTimestamp' => 0 ); $rc->save(); + + include_once( "UserMailer.php" ); + $wgEnotif = new EmailNotification (); + $wgEnotif->NotifyOnPageChangeOrNewpage( $timestamp, $title, $minor, $user, $comment, 0); } # Makes an entry in the database corresponding to a rename Index: includes/Skin.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/Skin.php,v retrieving revision 1.349 diff -u -b -r1.349 Skin.php --- includes/Skin.php 27 Apr 2005 07:48:13 -0000 1.349 +++ includes/Skin.php 28 Apr 2005 20:10:27 -0000 @@ -535,6 +535,52 @@ # do not show "You have new messages" text when we are viewing our # own talk page + global $wgShowNewtalkForUserOrUserTalkPage; + if ( $wgShowNewtalkForUserOrUserTalkPage ) { + # do always show "You have new messages" text + # checks are difficult and must consider many cases + $username = $wgUser->getName(); + $userpage = $wgContLang->getNsText( Namespace::getUser() ) . ":" . $username; + $usertitle = Title::newFromText( $userpage ); + + if ($wgUser->checkNotificationPendingForArticleOrTalk( $usertitle, NS_USER_TALK, $lvr )) { + $diff_oldid = ($lvr != 0) ? "diff=0&oldid={$lvr}" : ''; + $ns_usertalk = $wgContLang->getNsText( NS_USER_TALK ); + $newmsg_usertalklink = $this->makeKnownLink( $ns_usertalk . ':' . $username, wfMsg( 'newmsg_usertalk' ) ); + $newmsg_usertalklvrlink = $this->makeKnownLink( $ns_usertalk . ':' . $username, wfMsg( 'diff-to-lvr' ), + $diff_oldid, '', '', '', wfMsg( 'diff-to-lvr_tooltiptext' ) ); + $newmsg_usertalk = true; + }; + if ($wgUser->checkNotificationPendingForArticleOrTalk( $usertitle, NS_USER, $lvr )) { + $diff_oldid = ($lvr != 0) ? "diff=0&oldid={$lvr}" : ''; + $ns_user = $wgContLang->getNsText( NS_USER ); + $newmsg_userlink = $this->makeKnownLink( $ns_user . ':' . $username, wfMsg( 'newmsg_user' ) ); + $newmsg_userlvrlink = $this->makeKnownLink( $ns_user . ':' . $username, wfMsg( 'diff-to-lvr' ), + $diff_oldid, '', '', '', wfMsg( 'diff-to-lvr_tooltiptext' ) ); + $newmsg_user = true; + } + switch (true) { + case ( $newmsg_user && $newmsg_usertalk): { + $str = $newmsg_userlink . ' (' . $newmsg_userlvrlink . ') ' . wfMsg('newmsg_and') . + $newmsg_usertalklink . ' (' . $newmsg_usertalklvrlink . ')'; + break; + } + case (!$newmsg_user && $newmsg_usertalk): { + $str = $newmsg_usertalklink . ' (' . $newmsg_usertalklvrlink . ')'; + break; + } + case ( $newmsg_user && !$newmsg_usertalk): { + $str = $newmsg_userlink . ' (' . $newmsg_userlvrlink . ')'; + break; + } + default: { # this is the case for anon talk + $str = $this->makeKnownLink( $wgContLang->getNsText( NS_USER_TALK ).':'.$this->username, wfMsg( 'newmsg_usertalk' ) ); + } + } + $s .= ' | '. wfMsg( 'newmsg', $str . wfMsg('newmsg_page') . ''); + + } else { # old method, unchanged + if( $wgTitle->equals( $wgUser->getTalkPage() ) ) { $tl = $this->makeKnownLinkObj( $wgUser->getTalkPage(), wfMsg('newmessageslink') ); @@ -544,6 +590,7 @@ $wgOut->enableClientCache(false); } } + } $undelete = $this->getUndeleteLink(); if( !empty( $undelete ) ) { @@ -1095,7 +1142,7 @@ $wgUser->isLoggedIn() && # show only to signed in users 0 != $id; # we can only email to non-anons .. # '' != $id->getEmail() && # who must have an email address stored .. -# 0 != $id->getEmailauthenticationtimestamp() && # .. which is authenticated +# 0 != $id->getEmailConfirmationTimestamp() && # .. which is confirmed # 1 != $wgUser->getOption('disablemail'); # and not disabled } Index: includes/SkinTemplate.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/SkinTemplate.php,v retrieving revision 1.41 diff -u -b -r1.41 SkinTemplate.php --- includes/SkinTemplate.php 25 Apr 2005 10:37:25 -0000 1.41 +++ includes/SkinTemplate.php 28 Apr 2005 20:10:28 -0000 @@ -257,6 +257,47 @@ } else { $tpl->set('jsvarurl', false); } + + if ( $wgUser->getNewtalk() ) { + global $wgShowNewtalkForUserOrUserTalkPage; + if ( $wgShowNewtalkForUserOrUserTalkPage ) { + $usertitle = Title::newFromText( $this->userpage ); + if ($wgUser->checkNotificationPendingForArticleOrTalk( $usertitle, NS_USER_TALK, $lvr )) { + $diff_oldid = ($lvr != 0) ? "diff=0&oldid={$lvr}" : ''; + $ns_usertalk = $wgContLang->getNsText( NS_USER_TALK ); + $newmsg_usertalklink = $this->makeKnownLink( $ns_usertalk . ':' . $this->username, wfMsg( 'newmsg_usertalk' ) ); + $newmsg_usertalklvrlink = $this->makeKnownLink( $ns_usertalk . ':' . $this->username, wfMsg( 'diff-to-lvr' ), + $diff_oldid, '', '', '', wfMsg( 'diff-to-lvr_tooltiptext' ) ); + $newmsg_usertalk = true; + }; + if ($wgUser->checkNotificationPendingForArticleOrTalk( $usertitle, NS_USER, $lvr )) { + $diff_oldid = ($lvr != 0) ? "diff=0&oldid={$lvr}" : ''; + $ns_user = $wgContLang->getNsText( NS_USER ); + $newmsg_userlink = $this->makeKnownLink( $ns_user . ':' . $this->username, wfMsg( 'newmsg_user' ) ); + $newmsg_userlvrlink = $this->makeKnownLink( $ns_user . ':' . $this->username, wfMsg( 'diff-to-lvr' ), + $diff_oldid, '', '', '', wfMsg( 'diff-to-lvr_tooltiptext' ) ); + $newmsg_user = true; + } + switch (true) { + case ( $newmsg_user && $newmsg_usertalk): { + $str = $newmsg_userlink . ' (' . $newmsg_userlvrlink . ') ' . wfMsg('newmsg_and') . + $newmsg_usertalklink . ' (' . $newmsg_usertalklvrlink . ')'; + break; + } + case (!$newmsg_user && $newmsg_usertalk): { + $str = $newmsg_usertalklink . ' (' . $newmsg_usertalklvrlink . ')'; + break; + } + case ( $newmsg_user && !$newmsg_usertalk): { + $str = $newmsg_userlink . ' (' . $newmsg_userlvrlink . ')'; + break; + } + default: { # this is the case for anon talk + $str = $this->makeKnownLink( $wgContLang->getNsText( NS_USER_TALK ).':'.$this->username, wfMsg( 'newmsg_usertalk' ) ); + } + } + $ntl = wfMsg( 'newmsg', $str . wfMsg('newmsg_page') ); + } else { /* OLD METHOD */ if( $wgUser->getNewtalk() ) { $usertitle = $this->mUser->getUserPage(); $usertalktitle = $usertitle->getTalkPage(); @@ -273,6 +314,9 @@ } else { $ntl = ''; } + } + } + wfProfileOut( "$fname-stuff2" ); wfProfileIn( "$fname-stuff3" ); Index: includes/SpecialConfirmemail.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/SpecialConfirmemail.php,v retrieving revision 1.1 diff -u -b -r1.1 SpecialConfirmemail.php --- includes/SpecialConfirmemail.php 25 Apr 2005 18:38:16 -0000 1.1 +++ includes/SpecialConfirmemail.php 28 Apr 2005 20:10:28 -0000 @@ -46,6 +46,7 @@ $wgUser->isLoggedIn() && $wgUser->matchEditToken( $wgRequest->getVal( 'wpEditToken' ) ) ) { $result = $wgUser->sendConfirmationMail(); + require_once( 'WikiError.php' ); if( WikiError::isError( $result ) ) { return 'confirmemail_sendfailed'; } else { Index: includes/SpecialPage.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/SpecialPage.php,v retrieving revision 1.41 diff -u -b -r1.41 SpecialPage.php --- includes/SpecialPage.php 25 Apr 2005 18:38:16 -0000 1.41 +++ includes/SpecialPage.php 28 Apr 2005 20:10:28 -0000 @@ -66,8 +66,8 @@ $wgSpecialPages['Search'] = new UnlistedSpecialPage( 'Search' ); } -global $wgEmailAuthentication; -if( $wgEmailAuthentication ) { +global $wgEmailConfirmation; +if( $wgEmailConfirmation ) { $wgSpecialPages['Confirmemail'] = new UnlistedSpecialPage( 'Confirmemail' ); } Index: includes/SpecialPreferences.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/SpecialPreferences.php,v retrieving revision 1.107 diff -u -b -r1.107 SpecialPreferences.php --- includes/SpecialPreferences.php 27 Apr 2005 22:55:20 -0000 1.107 +++ includes/SpecialPreferences.php 28 Apr 2005 20:10:28 -0000 @@ -33,6 +33,7 @@ var $mUserLanguage, $mUserVariant; var $mSearch, $mRecent, $mHourDiff, $mSearchLines, $mSearchChars, $mAction; var $mReset, $mPosted, $mToggles, $mSearchNs, $mRealName, $mImageSize; + var $mEnotifNewPages; /** * Constructor @@ -54,6 +55,7 @@ $this->mUserEmail = $request->getVal( 'wpUserEmail' ); $this->mRealName = $wgAllowRealName ? $request->getVal( 'wpRealName' ) : ''; $this->mEmailFlag = $request->getCheck( 'wpEmailFlag' ) ? 1 : 0; + $this->mEnotifNewPages = $request->getCheck( 'wpEnotifNewPages' ) ? 1 : 0; $this->mNick = $request->getVal( 'wpNick' ); $this->mUserLanguage = $request->getVal( 'wpUserLanguage' ); $this->mUserVariant = $request->getVal( 'wpUserVariant' ); @@ -182,7 +184,9 @@ function savePreferences() { global $wgUser, $wgLang, $wgOut; global $wgEnableUserEmail, $wgEnableEmail; - global $wgEmailAuthentication, $wgMinimalPasswordLength; + global $wgEmailConfirmation, $wgMinimalPasswordLength; + global $wgEmailNotificationForNewPages,$wgEmailNotificationForNewPagesAllowedForAll; + if ( '' != $this->mNewpass ) { if ( $this->mNewpass != $this->mRetypePass ) { @@ -233,6 +237,12 @@ foreach ( $this->mToggles as $tname => $tvalue ) { $wgUser->setOption( $tname, $tvalue ); } + if ( $wgEmailNotificationForNewPages && + ( $wgEmailNotificationForNewPagesAllowedForAll || $wgUser->isBureaucratOrDeveloperOrSysop() ) ) { + $wgUser->setEmailNotificationForNewPages( $this->mEnotifNewPages ); + } else { + $wgUser->setEmailNotificationForNewPages( false ); + } $wgUser->setCookies(); $wgUser->saveSettings(); @@ -244,16 +254,24 @@ # the user has supplied a new email address on the login page if( $wgUser->isValidEmailAddr( $newadr ) ) { $wgUser->mEmail = $newadr; # new behaviour: set this new emailaddr from login-page into user database record - $wgUser->mEmailAuthenticated = null; # but flag as "dirty" = unauthenticated + + global $wgEmailConfirmationRequiredForAll; + if ( !$wgEmailConfirmationRequiredForAll && $wgUser->isBureaucratOrDeveloperOrSysop() ) { + $wgUser->mEmailConfirmed = wfTimestampNow( TS_MW ); $wgUser->saveSettings(); - if ($wgEmailAuthentication) { - # Mail a temporary password to the dirty address. + } else { + $wgUser->mEmailConfirmed = null; # but flag as "dirty" = unconfirmed + $wgUser->saveSettings(); + if ($wgEmailConfirmation) { + # Mail the confirmation link (token) to the unconfirmed address. # User can come back through the confirmation URL to re-enable email. $result = $wgUser->sendConfirmationMail(); + require_once( 'WikiError.php' ); if( WikiError::isError( $result ) ) { - $error = wfMsg( 'mailerror', $result->getMessage() ); + $error = wfMsg( 'confirmemail_sendfailed' ); } else { - $error = wfMsg( 'passwordsentforemailauthentication', $wgUser->getName() ); + $error = wfMsg( 'confirmemail_sent' ); + } } } } else { @@ -279,7 +297,7 @@ $this->mOldpass = $this->mNewpass = $this->mRetypePass = ''; $this->mUserEmail = $wgUser->getEmail(); - $this->mUserEmailAuthenticationtimestamp = $wgUser->getEmailAuthenticationtimestamp(); + $this->mEnotifNewPages = $wgUser->getEmailNotificationForNewPages(); $this->mRealName = ($wgAllowRealName) ? $wgUser->getRealName() : ''; $this->mUserLanguage = $wgUser->getOption( 'language' ); if( empty( $this->mUserLanguage ) ) { @@ -394,8 +412,9 @@ global $wgAllowRealName, $wgImageLimits, $wgThumbLimits; global $wgLanguageNames, $wgDisableLangConversion; global $wgEmailNotificationForWatchlistPages, $wgEmailNotificationForUserTalkPages,$wgEmailNotificationForMinorEdits; - global $wgRCShowWatchingUsers, $wgEmailNotificationRevealPageEditorAddress; - global $wgEnableEmail, $wgEnableUserEmail, $wgEmailAuthentication; + global $wgRCShowWatchingUsers, $wgRCShowCurrentRevisionOnly, $wgEmailNotificationRevealPageEditorAddress; + global $wgEnableEmail, $wgEnableUserEmail, $wgEmailConfirmation; + global $wgEmailNotificationForNewPages,$wgEmailNotificationForNewPagesAllowedForAll; global $wgContLanguageCode; $wgOut->setPageTitle( wfMsg( 'preferences' ) ); @@ -429,19 +448,19 @@ if ( $this->mEmailFlag ) { $emfc = 'checked="checked"'; } else { $emfc = ''; } - if ($wgEmailAuthentication && ($this->mUserEmail != '') ) { - if( $wgUser->getEmailAuthenticationTimestamp() ) { - $emailauthenticated = wfMsg('emailauthenticated',$wgLang->timeanddate($wgUser->getEmailAuthenticationTimestamp(), true ) ).'
'; + if ($wgEmailConfirmation && ($this->mUserEmail != '') ) { + if( $wgUser->getEmailConfirmationTimestamp() ) { + $emailconfirmed = wfMsg('emailconfirmed',$wgUser->getEmail(), $wgLang->timeanddate($wgUser->getEmailConfirmationTimestamp(), true ) ).'
'; $disabled = ''; } else { $skin = $wgUser->getSkin(); - $emailauthenticated = wfMsg('emailnotauthenticated').'
' . + $emailconfirmed = wfMsg('emailnotconfirmed').'
' . $skin->makeKnownLinkObj( Title::makeTitle( NS_SPECIAL, 'Confirmemail' ), wfMsg( 'emailconfirmlink' ) ); - $disabled = ' '.wfMsg('disableduntilauthent'); + $disabled = ' '.wfMsg('disableduntilconfirmation'); } } else { - $emailauthenticated = ''; + $emailconfirmed = ''; } if ($this->mUserEmail == '') { @@ -454,6 +473,15 @@ $enotifusertalkpages = ($wgEmailNotificationForUserTalkPages) ? $this->getToggle( 'enotifusertalkpages', $disabled) : ''; $enotifminoredits = ($wgEmailNotificationForMinorEdits) ? $this->getToggle( 'enotifminoredits', $disabled) : ''; $enotifrevealaddr = ($wgEmailNotificationRevealPageEditorAddress) ? $this->getToggle( 'enotifrevealaddr', $disabled) : ''; + if ( $wgEmailNotificationForNewPages && + ( $wgEmailNotificationForNewPagesAllowedForAll || $wgUser->isBureaucratOrDeveloperOrSysop() ) ) { + if ( $this->mEnotifNewPages ) { $enotifnewpagec = 'checked="checked"'; } + else { $enotifnewpagec = ''; } + $enotifnewpages = "
"; + } else { + $enotifnewpages = ''; + } $prefs_help_email_enotif = ( $wgEmailNotificationForWatchlistPages || $wgEmailNotificationForUserTalkPages) ? ' ' . wfMsg('prefs-help-email-enotif') : ''; $prefs_help_realname = ''; @@ -557,10 +585,11 @@ if ($wgEnableEmail) { $wgOut->addHTML( '
' . wfMsg( 'email' ) . '' ); $wgOut->addHTML( - $emailauthenticated. + $emailconfirmed. $enotifrevealaddr. $enotifwatchlistpages. $enotifusertalkpages. + $enotifnewpages. $enotifminoredits ); if ($wgEnableUserEmail) { $emf = wfMsg( 'emailflag' ); @@ -700,7 +729,7 @@ "hideminor", ($wgRCShowWatchingUsers) ? 'shownumberswatching' : false, "usenewrc", - "rcusemodstyle", + ($wgRCShowCurrentRevisionOnly) ? 'rccurrevonly' : false, array( 'showupdated', wfMsg('updatedmarker') ) ) ) . "
Index: includes/SpecialRecentchanges.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/SpecialRecentchanges.php,v retrieving revision 1.63 diff -u -b -r1.63 SpecialRecentchanges.php --- includes/SpecialRecentchanges.php 25 Apr 2005 10:08:51 -0000 1.63 +++ includes/SpecialRecentchanges.php 28 Apr 2005 20:10:29 -0000 @@ -19,7 +19,7 @@ global $wgUser, $wgOut, $wgLang, $wgContLang, $wgTitle, $wgMemc, $wgDBname; global $wgRequest, $wgSitename, $wgLanguageCode, $wgContLanguageCode; global $wgFeedClasses, $wgUseRCPatrol; - global $wgRCShowWatchingUsers, $wgShowUpdatedMarker; + global $wgRCShowCurrentRevisionOnly,$wgRCShowWatchingUsers, $wgShowUpdatedMarker; global $wgLinkCache; $fname = 'wfSpecialRecentchanges'; @@ -117,12 +117,14 @@ $patrLink = $sk->makeKnownLink( $wgContLang->specialPage( 'Recentchanges' ), $showhide[1-$hidepatrolled], wfArrayToCGI( array( 'hidepatrolled' => 1-$hidepatrolled ), $urlparams ) ); + $currevonly = ($wgRCShowCurrentRevisionOnly && $wgUser->getOption('rccurrevonly')) ? 'AND rc_this_oldid=0 ' : '' ; + $uid = $wgUser->getID(); // Perform query - $sql2 = "SELECT $recentchanges.*" . ($uid ? ",wl_user,wl_notificationtimestamp" : "") . " FROM $recentchanges " . + $sql2 = "SELECT $recentchanges.*" . ($uid ? ",wl_user,wl_notificationtimestamp,wl_lastvisitedrevision" : "") . " FROM $recentchanges " . ($uid ? "LEFT OUTER JOIN $watchlist ON wl_user={$uid} AND wl_title=rc_title AND wl_namespace=rc_namespace " : "") . - "WHERE rc_timestamp > '{$cutoff}' {$hidem} " . + "WHERE rc_timestamp > '{$cutoff}' {$hidem} " . $currevonly . "ORDER BY rc_timestamp DESC LIMIT {$limit}"; $res = $dbr->query( $sql2, $fname ); @@ -196,6 +198,7 @@ } else { $rc->numberofWatchingusers = 0; } + $rc->lastvisitedrevision = $obj->wl_lastvisitedrevision; $s .= $list->recentChangesLine( $rc, !empty( $obj->wl_user ) ); --$limit; } Index: includes/SpecialUserlogin.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/SpecialUserlogin.php,v retrieving revision 1.71 diff -u -b -r1.71 SpecialUserlogin.php --- includes/SpecialUserlogin.php 25 Apr 2005 18:38:17 -0000 1.71 +++ includes/SpecialUserlogin.php 28 Apr 2005 20:10:29 -0000 @@ -237,7 +237,6 @@ * @access private */ function processLogin() { - global $wgUser; if ( '' == $this->mName ) { $this->mainLoginForm( wfMsg( 'noname' ) ); @@ -287,8 +286,33 @@ $wgUser = $u; $wgUser->setCookies(); + # auto-confirm e-mail address for super-users + if ( $u->isBureaucratOrDeveloperOrSysop() && !$wgEmailConfirmationRequiredForAll && !$u->getEmailConfirmationTimestamp() ) { + $u->mEmailConfirmed = wfTimestampNow( TS_MW ); + } + $wgUser->saveSettings(); +# if ( !$wgEmailConfirmation || $alreadyconfirmed ) { +# $confirmed = ''; +# $mailmsg = ''; +# } elseif ($u->mEmailConfirmationtimestamp != wfTimestampOrNull(0) ) { +# $confirmed = ' ' . wfMsg( 'emailconfirmed', $u->getEmail(), $wgLang->timeanddate( $u->mEmailConfirmationtimestamp, true ) ); +# } else { +# $confirmed = ' ' . wfMsg( 'emailnotconfirmed' ); +# } + +# if ( $wgEmailConfirmation ) { + if ( !$wgEmailConfirmationRequiredForAll && $u->isBureaucratOrDeveloperOrSysop() ) { + $u->mEmailConfirmed = wfTimestampNow( TS_MW ); + } +# } elseif ( $u->getEmailConfirmationTimestamp() ) { +# $emailconfirmed = ' ' . wfMsg( 'emailconfirmed', $u->getEmail(), $wgLang->timeanddate( $u->getEmailConfirmationTimestamp(), true ) ); +# } else { +# $emailconfirmed = ' ' . wfMsg( 'emailnotconfirmed' ); +# } +# } + if( $this->hasSessionCookie() ) { return $this->successfulLogin( wfMsg( 'loginsuccess', $wgUser->getName() ) ); } else { Index: includes/SpecialWatchlist.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/SpecialWatchlist.php,v retrieving revision 1.50 diff -u -b -r1.50 SpecialWatchlist.php --- includes/SpecialWatchlist.php 26 Mar 2005 21:26:25 -0000 1.50 +++ includes/SpecialWatchlist.php 28 Apr 2005 20:10:29 -0000 @@ -206,7 +206,7 @@ $use_index = $dbr->useIndexClause( $x ); $sql = "SELECT page_namespace,page_title,rev_comment, page_id, - rev_user,rev_user_text,rev_timestamp,rev_minor_edit,page_is_new,wl_notificationtimestamp + rev_user,rev_user_text,rev_timestamp,rev_minor_edit,page_is_new,wl_notificationtimestamp,wl_lastvisitedrevision FROM $watchlist,$page,$revision $use_index WHERE wl_user=$uid $andHideOwn @@ -266,7 +266,7 @@ } else { $rc->numberofWatchingusers = 0; } - + $rc->lastvisitedrevision = $obj->wl_lastvisitedrevision; $s .= $list->recentChangesLine( $rc, true); } $s .= $list->endRecentChangesList(); Index: includes/User.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/User.php,v retrieving revision 1.140 diff -u -b -r1.140 User.php --- includes/User.php 25 Apr 2005 18:38:38 -0000 1.140 +++ includes/User.php 28 Apr 2005 20:10:30 -0000 @@ -23,7 +23,8 @@ * @access private */ var $mId, $mName, $mPassword, $mEmail, $mNewtalk; - var $mEmailAuthenticated; + var $mEmailConfirmed; + var $mEmailNotificationForNewPages; var $mRights, $mOptions; var $mDataLoaded, $mNewpassword; var $mSkin; @@ -192,7 +193,8 @@ $this->mNewtalk = -1; $this->mName = $wgIP; $this->mRealName = $this->mEmail = ''; - $this->mEmailAuthenticated = null; + $this->mEmailConfirmed = null; + $this->mEmailNotificationForNewPages = 0; $this->mPassword = $this->mNewpassword = ''; $this->mRights = array(); $this->mGroups = array(); @@ -501,14 +503,15 @@ $dbr =& wfGetDB( DB_SLAVE ); $s = $dbr->selectRow( 'user', array( 'user_name','user_password','user_newpassword','user_email', - 'user_email_authenticated', + 'user_email_confirmed', 'user_emailnotificationfornewpages', 'user_real_name','user_options','user_touched', 'user_token' ), array( 'user_id' => $this->mId ), $fname ); if ( $s !== false ) { $this->mName = $s->user_name; $this->mEmail = $s->user_email; - $this->mEmailAuthenticated = wfTimestampOrNull( TS_MW, $s->user_email_authenticated ); + $this->mEmailConfirmed = wfTimestampOrNull( TS_MW, $s->user_email_confirmed ); + $this->mEmailNotificationForNewPages = $s->user_emailnotificationfornewpages; $this->mRealName = $s->user_real_name; $this->mPassword = $s->user_password; $this->mNewpassword = $s->user_newpassword; @@ -576,34 +579,30 @@ # Load the newtalk status if it is unloaded (mNewtalk=-1) if( $this->mNewtalk == -1 ) { $this->mNewtalk = 0; # reset talk page status - + $dbr =& wfGetDB( DB_SLAVE ); + if($this->mId) { + $res = $dbr->select( 'user_newtalk', 1, array( 'user_id' => $this->mId ), $fname ); + if ( $dbr->numRows($res)>0 ) { + $this->mNewtalk= 1; + } + $dbr->freeResult( $res ); + } else { # Check memcached separately for anons, who have no # entire User object stored in there. - if( !$this->mId ) { global $wgDBname, $wgMemc; $key = "$wgDBname:newtalk:ip:{$this->mName}"; $newtalk = $wgMemc->get( $key ); - if( is_integer( $newtalk ) ) { - $this->mNewtalk = $newtalk ? 1 : 0; - return (bool)$this->mNewtalk; - } - } + if( ! is_integer( $newtalk ) ){ + $res = $dbr->select( 'user_newtalk', 1, array( 'user_ip' => $this->mName ), $fname ); - $dbr =& wfGetDB( DB_SLAVE ); - $res = $dbr->select( 'watchlist', - array( 'wl_user' ), - array( 'wl_title' => $this->getTitleKey(), - 'wl_namespace' => NS_USER_TALK, - 'wl_user' => $this->mId, - 'wl_notificationtimestamp != 0' ), - 'User::getNewtalk' ); - if( $dbr->numRows($res) > 0 ) { - $this->mNewtalk = 1; - } + $this->mNewtalk = $dbr->numRows( $res ) > 0 ? 1 : 0; $dbr->freeResult( $res ); - if( !$this->mId ) { $wgMemc->set( $key, $this->mNewtalk, time() ); // + 1800 ); + } else { + $this->mNewtalk = $newtalk ? 1 : 0; + return (bool)$this->mNewtalk; + } } } @@ -693,9 +692,19 @@ return $this->mEmail; } - function getEmailAuthenticationTimestamp() { + function getEmailConfirmationTimestamp() { $this->loadFromDatabase(); - return $this->mEmailAuthenticated; + return $this->mEmailConfirmed; + } + + function getEmailNotificationForNewPages() { + $this->loadFromDatabase(); + return $this->mEmailNotificationForNewPages; + } + + function setEmailNotificationForNewPages( $val ) { + $this->loadFromDatabase(); + $this->mEmailNotificationForNewPages = $val; } function setEmail( $str ) { @@ -775,6 +784,18 @@ } /** + * Check if a user is bureaucrat, developer, sysop + */ + function isBureaucratOrDeveloperOrSysop() { + $this->loadFromDatabase(); + if ( 0 == $this->mId ) { return false; } + + return ( in_array( 'sysop', $this->mRights ) || + in_array( 'developer', $this->mRights ) || + in_array( 'bureaucrat', $this->mRights ) ); + } + + /** * Check if a user is sysop * Die with backtrace. Use User:isAllowed() instead. * @deprecated @@ -907,6 +928,36 @@ } /** + * Check the user's notification timestamp for the given title and Namespace + * + * returns: status of pending notification false, true + * out: lvr id of last visited revsion + */ + function checkNotificationPendingForArticleOrTalk( $title, $Ns, &$lvr ) { + $userid = $this->getId(); + if ($userid==0) + return; + + $dbr =& wfGetDB( DB_MASTER ); + $s = $dbr->selectRow( 'watchlist', + array( + 'wl_notificationtimestamp', + 'wl_lastvisitedrevision' + ), array( /* WHERE */ + 'wl_title' => $title->getDBkey(), + 'wl_namespace' => $Ns, + 'wl_user' => $this->getId() + ), 'User::clearNotification' + ); + if ( $s === false ) { + return false; + } else { + $lvr = $s->wl_lastvisitedrevision; + return ($s->wl_notificationtimestamp != wfTimestampOrNull() ); + } + } + + /** * Clear the user's notification timestamp for the given title. * If e-notif e-mails are on, they will receive notification mails on * the next change of the page if it's watched etc. @@ -918,12 +969,13 @@ $dbw =& wfGetDB( DB_MASTER ); $success = $dbw->update( 'watchlist', array( /* SET */ - 'wl_notificationtimestamp' => 0 + 'wl_notificationtimestamp' => $dbw->timestampOrNull(), + 'wl_lastvisitedrevision' => NULL ), array( /* WHERE */ 'wl_title' => $title->getDBkey(), 'wl_namespace' => $title->getNamespace(), 'wl_user' => $this->getId() - ), 'User::clearLastVisited' + ), 'User::clearNotification' ); } @@ -943,15 +995,15 @@ $dbw =& wfGetDB( DB_MASTER ); $success = $dbw->update( 'watchlist', array( /* SET */ - 'wl_notificationtimestamp' => 0 + 'wl_notificationtimestamp' => $dbw->timestampOrNull(), + 'wl_lastvisitedrevision' => NULL ), array( /* WHERE */ 'wl_user' => $currentUser - ), 'UserMailer::clearAll' + ), 'User::clearAllNotifications' ); - - # we also need to clear here the "you have new message" notification for the own user_talk page - # This is cleared one page view later in Article::viewUpdates(); } + $this->setnewtalk(0); + $this->saveNewtalk(); } /** @@ -1024,23 +1076,14 @@ global $wgMemc, $wgDBname; $fname = 'User::saveSettings'; - $dbw =& wfGetDB( DB_MASTER ); - if ( ! $this->getNewtalk() ) { - # Delete the watchlist entry for user_talk page X watched by user X - $dbw->delete( 'watchlist', - array( 'wl_user' => $this->mId, - 'wl_title' => $this->getTitleKey(), - 'wl_namespace' => NS_USER_TALK ), - $fname ); if( !$this->mId ) { # Anon users have a separate memcache space for newtalk # since they don't store their own info. Trim... $wgMemc->delete( "$wgDBname:newtalk:ip:{$this->mName}" ); - } + return; } - if ( 0 == $this->mId ) { return; } - + $dbw =& wfGetDB( DB_MASTER ); $dbw->update( 'user', array( /* SET */ 'user_name' => $this->mName, @@ -1048,7 +1091,8 @@ 'user_newpassword' => $this->mNewpassword, 'user_real_name' => $this->mRealName, 'user_email' => $this->mEmail, - 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ), + 'user_email_confirmed' => $dbw->timestampOrNull( $this->mEmailConfirmed ), + 'user_emailnotificationfornewpages' => $this->mEmailNotificationForNewPages, 'user_options' => $this->encodeOptions(), 'user_touched' => $dbw->timestamp($this->mTouched), 'user_token' => $this->mToken @@ -1075,6 +1119,39 @@ } } + /** + * Save value of new talk flag. + */ + function saveNewtalk() { + global $wgDBname, $wgMemc; + + $fname = 'User::saveNewtalk'; + + if ( wfReadOnly() ) { return ; } + + if ($this->getID() != 0) { + $field = 'user_id'; + $value = $this->getID(); + $key = "$wgDBname:user:id:$this->mId"; + } else { + $field = 'user_ip'; + $value = $this->mName; + $key = "$wgDBname:newtalk:ip:$this->mName"; + } + + $dbr =& wfGetDB( DB_SLAVE ); + $dbw =& wfGetDB( DB_MASTER ); + + $res = $dbr->selectField('user_newtalk', $field, array($field => $value), $fname); + + if ($res !== false && $this->mNewtalk == 0) { + $dbw->delete('user_newtalk', array($field => $value), $fname); + $wgMemc->delete($key); + } else if ($res === false && $this->mNewtalk == 1) { + $dbw->insert('user_newtalk', array($field => $value), $fname); + $wgMemc->delete($key); + } + } /** * Checks if a user with the given name exists, returns the ID @@ -1108,7 +1185,8 @@ 'user_password' => $this->mPassword, 'user_newpassword' => $this->mNewpassword, 'user_email' => $this->mEmail, - 'user_email_authenticated' => $dbw->timestampOrNull( $this->mEmailAuthenticated ), + 'user_email_confirmed' => $dbw->timestampOrNull( $this->mEmailConfirmed ), + 'user_emailnotificationfornewpages' => $this->mEmailNotificationForNewPages, 'user_real_name' => $this->mRealName, 'user_options' => $this->encodeOptions(), 'user_token' => $this->mToken @@ -1282,7 +1360,7 @@ # If e-mail confirmation hasn't been done already, # we may as well confirm it here -- the user can only # get this password via e-mail. - $this->mEmailAuthenticated = wfTimestampNow(); + $this->mEmailConfirmed = wfTimestampNow(); # use the temporary one-time password only once: clear it now ! $this->mNewpassword = ''; @@ -1435,7 +1513,7 @@ */ function confirmEmail() { $this->loadFromDatabase(); - $this->mEmailAuthenticated = wfTimestampNow(); + $this->mEmailConfirmed = wfTimestampNow(); $this->saveSettings(); return true; } @@ -1462,20 +1540,20 @@ * Is this user's e-mail address valid-looking and confirmed within * limits of the current site configuration? * - * If $wgEmailAuthentication is on, this may require the user to have + * If $wgEmailConfirmation is on, this may require the user to have * confirmed their address by returning a code or using a password * sent to the address from the wiki. * * @return bool */ function isEmailConfirmed() { - global $wgEmailAuthentication; + global $wgEmailConfirmation; $this->loadFromDatabase(); if( $this->isAnon() ) return false; if( !$this->isValidEmailAddr( $this->mEmail ) ) return false; - if( $wgEmailAuthentication && !$this->getEmailAuthenticationTimestamp() ) + if( $wgEmailConfirmation && !$this->getEmailConfirmationTimestamp() ) return false; return true; } Index: includes/UserMailer.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/UserMailer.php,v retrieving revision 1.22 diff -u -b -r1.22 UserMailer.php --- includes/UserMailer.php 27 Apr 2005 21:26:39 -0000 1.22 +++ includes/UserMailer.php 28 Apr 2005 20:10:30 -0000 @@ -25,8 +25,6 @@ * @package MediaWiki */ -require_once( 'WikiError.php' ); - /** * Provide mail capabilities * @param string $string ???? @@ -183,17 +181,23 @@ * @param $currentMinorEdit * @param $oldid (default: false) */ - function NotifyOnPageChange($currentUser, $currentPage, $currentNs, $timestamp, $currentSummary, $currentMinorEdit, $oldid=false) { + function NotifyOnPageChangeOrNewpage($timestamp, $currentTitleObj, $currentMinorEdit, $pageeditorUserObj, $currentSummary, $oldid=false) { # we use $wgEmergencyContact as sender's address - global $wgUser, $wgLang, $wgEmergencyContact; + global $wgLang, $wgEmergencyContact; global $wgEmailNotificationForWatchlistPages, $wgEmailNotificationForMinorEdits; global $wgEmailNotificationSystembeep, $wgEmailNotificationForUserTalkPages; + global $wgEmailNotificationForNewPages; global $wgEmailNotificationRevealPageEditorAddress; global $wgEmailNotificationMailsSentFromPageEditor; - global $wgEmailAuthentication; + global $wgEmailConfirmation; global $beeped; + $currentPage = $currentTitleObj->getDBKey(); + $currentNs = $currentTitleObj->getNamespace(); + + $initialised = false; + # 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 @@ -206,14 +210,16 @@ && (!$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'); + $res = $dbr->select( 'watchlist', + 'wl_user', + "wl_title ='".$dbr->strencode($currentPage). + "' AND wl_namespace ='".$currentNs. + "' AND wl_user <>".$pageeditorUserObj->getID(). + " AND ".$dbr->wl_notificationtimestampIsNULL(), + 'UserMailer::NotifyOnPageChangeOrNewpage'); # if anyone is watching ... set up the email message text which is - # common for all receipients ... + # common for all recipients ... if ( $dbr->numRows( $res ) > 0 ) { # This is a switch for one beep on the server when sending notification mails @@ -226,21 +232,23 @@ $article->mTitle = $currentPage; $article->mOldid = $oldid; - $mail = $this->composeCommonMailtext( $wgUser, $article ); - $watchingUser = new User(); + $mail = $this->composeCommonMailtext( $pageeditorUserObj, $article ); + $watchingUserObj = new User(); + $initialised = true; # ... 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() ) ) { + $watchingUserObj->setID($wuser->wl_user); + if ( ( $enotifwatchlistpage && $watchingUserObj->getOption('enotifwatchlistpages') ) || + ( $enotifusertalkpage && $watchingUserObj->getOption('enotifusertalkpages') ) + && (!$currentMinorEdit || ($wgEmailNotificationForMinorEdits && $watchingUserObj->getOption('enotifminoredits') ) ) + && ($watchingUserObj->getEmail() != '') + && (!$wgEmailConfirmation || ($watchingUserObj->isEmailConfirmed() ) ) ) { # ... adjust remaining text and page edit time placeholders # which needs to be personalized for each user - $sent = $this->composeAndSendPersonalisedMail( $watchingUser, $mail, $article ); + $sent = $this->composeAndSendPersonalisedMail( $watchingUserObj, $mail, $article ); /* the beep here beeps once when a watched-listed page is changed */ if ($sent && !$beeped && ($wgEmailNotificationSystembeep != '') ) { $last_line = system($wgEmailNotificationSystembeep); @@ -250,19 +258,48 @@ # 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 + # save also the last seen revision of that page for (lvr) links $dbw =& wfGetDB( DB_MASTER ); $succes = $dbw->update( 'watchlist', array( /* SET */ - 'wl_notificationtimestamp' => $article->mTimestamp + 'wl_notificationtimestamp' => wfTimestamp(TS_MW, $article->mTimestamp), + 'wl_lastvisitedrevision' => $oldid ), array( /* WHERE */ 'wl_title' => $currentPage, 'wl_namespace' => $currentNs, 'wl_user' => $wuser->wl_user - ), 'UserMailer::NotifyOnChange' + ), 'UserMailer::NotifyOnPageChangeOrNewpage' ); } # for every watching user } # if anyone is watching } # if $wgEmailNotificationForWatchlistPages = true + + if ( $wgEmailNotificationForNewPages && isset($oldid) && $oldid==0 ) { + $dbr =& wfGetDB( DB_MASTER ); + $res = $dbr->select( 'user', + 'user_id', + 'user_emailnotificationfornewpages=1 AND user_id<>'.$pageeditorUserObj->getID(), + 'UserMailer::NotifyOnPageChangeOrNewpage' ); + # Still to-do: + # We must not send new page notification to a user, who already is watching this page + for ($i = 1; $i <= $dbr->numRows( $res ); $i++) { + if (!$initialised) { # initialise if not yet done + $article->mTimestamp = $timestamp; + $article->mSummary = $currentSummary; + $article->mMinorEdit = $currentMinorEdit; + $article->mNamespace = $currentNs; + $article->mTitle = $currentPage; + $article->mOldid = $oldid; + $mail = $this->composeCommonMailtext( $pageeditorUserObj, $article ); + $watchingUserObj = new User(); + } + + $wuser = $dbr->fetchObject( $res ); + $watchingUserObj->setID($wuser->user_id); + $sent = $this->composeAndSendPersonalisedMail( $watchingUserObj, $mail, $article ); + } + } # notifications for a new page + } # function NotifyOnChange /** @@ -270,7 +307,7 @@ * @param Article $article * @access private */ - function composeCommonMailtext( $pageeditorUser, $article ) { + function composeCommonMailtext( $pageeditorUserObj, $article ) { global $wgLang, $wgEmergencyContact; global $wgEmailNotificationRevealPageEditorAddress; global $wgEmailNotificationMailsSentFromPageEditor; @@ -293,15 +330,19 @@ # 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; + $keys['$CHANGEDORCREATED'] = wfMsg( 'changed' ); } else { $keys['$NEWPAGE'] = wfMsg( 'email_notification_newpagetext' ); # clear $OLDID placeholder in the message template $keys['$OLDID'] = ''; + $keys['$CHANGEDORCREATED'] = wfMsg( 'created' ); } + $subject = strtr( $subject, $keys ); $body = strtr( $body, $keys ); $pagetitle = $article->mTitle; @@ -314,20 +355,19 @@ $keys['%24PAGETITLE'] = $pagetitle; # needed for the {{localurl:$PAGETITLE}} in the messagetext, "$" appears here as "%24" $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['$PAGEEDITDATEUTC'] = $wgLang->timeanddate( $article->mTimestamp, false, false, false, true ); $keys['$PAGEMINOREDIT'] = $medit; $keys['$PAGESUMMARY'] = $summary; - # 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(); + $name = $pageeditorUserObj->getName(); $adminAddress = 'WikiAdmin <' . $wgEmergencyContact . '>'; - $editorAddress = $name . ' <' . $pageeditorUser->getEmail() . '>'; + $editorAddress = $name . ' <' . $pageeditorUserObj->getEmail() . '>'; if( $wgEmailNotificationRevealPageEditorAddress - && ( $pageeditorUser->getEmail() != '' ) - && $pageeditorUser->getOption( 'enotifrevealaddr' ) ) { + && ( $pageeditorUserObj->getEmail() != '' ) + && $pageeditorUserObj->getOption( 'enotifrevealaddr' ) ) { if( $wgEmailNotificationMailsSentFromPageEditor ) { $from = $editorAddress; } else { @@ -341,7 +381,7 @@ $keys['$PAGEEDITORNAMEANDEMAILADDR'] = $replyto; } - if( $pageeditorUser->isIP( $name ) ) { + if( $pageeditorUserObj->isIP( $name ) ) { #real anon (user:xxx.xxx.xxx.xxx) $anon = $name . ' (anonymous user)'; $anonUrl = wfUrlencode( $name ) . ' (anonymous user)'; @@ -356,8 +396,8 @@ $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['%24PAGEEDITORE'] = $pageeditorUserObj->getName(); + $keys['$PAGEEDITORE'] = $pageeditorUserObj->getName(); $keys['$PAGEEDITOR'] = $name; } $body = strtr( $body, $keys ); @@ -378,20 +418,20 @@ * timestamp in proper timezone, etc) and sends it out. * Returns true if the mail was sent successfully. * - * @param User $watchingUser + * @param User $watchingUserObj * @param object $mail * @param Article $article * @return bool * @access private */ - function composeAndSendPersonalisedMail( $watchingUser, $mail, $article ) { + function composeAndSendPersonalisedMail( $watchingUserObj, $mail, $article ) { global $wgLang; - $to = $watchingUser->getName() . ' <' . $watchingUser->getEmail() . '>'; - $body = str_replace( '$WATCHINGUSERNAME', $watchingUser->getName() , $mail->body ); - $body = str_replace( '$WATCHINGUSEREMAILADDR', $watchingUser->getEmail(), $body ); + $to = $watchingUserObj->getName() . ' <' . $watchingUserObj->getEmail() . '>'; + $body = str_replace( '$WATCHINGUSERNAME', $watchingUserObj->getName() , $mail->body ); + $body = str_replace( '$WATCHINGUSEREMAILADDR', $watchingUserObj->getEmail(), $body ); - $timecorrection = $watchingUser->getOption( 'timecorrection' ); + $timecorrection = $watchingUserObj->getOption( 'timecorrection' ); if( !$timecorrection ) { # fail safe - I prefer it. TomGries $timecorrection = '00:00'; @@ -400,7 +440,7 @@ # 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( $article->mTimestamp, true, false, $timecorrection, true), $body); $error = userMailer( $to, $mail->from, $mail->subject, $body, $mail->replyto ); Index: includes/WatchedItem.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/WatchedItem.php,v retrieving revision 1.16 diff -u -b -r1.16 WatchedItem.php --- includes/WatchedItem.php 27 Jan 2005 17:56:04 -0000 1.16 +++ includes/WatchedItem.php 28 Apr 2005 20:10:30 -0000 @@ -11,12 +11,8 @@ class WatchedItem { var $mTitle, $mUser; - /** - * Create a WatchedItem object with the given user and title - * @todo document - * @private - */ - function &fromUserTitle( &$user, &$title ) { + # Create a WatchedItem object with the given user and title + /* static */ function &fromUserTitle( &$user, &$title ) { $wl = new WatchedItem; $wl->mUser =& $user; $wl->mTitle =& $title; @@ -26,7 +22,6 @@ # The change results in talk-pages not automatically included in watchlists, when their parent page is included # $wl->ns = $title->getNamespace() & ~1; $wl->ns = $title->getNamespace(); - $wl->ti = $title->getDBkey(); return $wl; } @@ -42,7 +37,8 @@ /** * Is mTitle being watched by mUser? */ - function isWatched() { + function isWatched() + { # Pages and their talk pages are considered equivalent for watching; # remember that talk namespaces are numbered as page namespace+1. global $wgMemc; @@ -60,31 +56,30 @@ return $iswatched; } - /** - * @todo document - */ function addWatch() { - $fname = 'WatchedItem::addWatch'; + $fname = "WatchedItem::addWatch"; # REPLACE instead of INSERT because occasionally someone # accidentally reloads a watch-add operation. $dbw =& wfGetDB( DB_MASTER ); - $dbw->replace( 'watchlist', array(array('wl_user', 'wl_namespace', 'wl_title', 'wl_notificationtimestamp')), + $dbw->replace( 'watchlist', array(array('wl_user', 'wl_namespace', 'wl_title', 'wl_notificationtimestamp', 'wl_lastvisitedrevision' )), array( 'wl_user' => $this->id, 'wl_namespace' => ($this->ns & ~1), 'wl_title' => $this->ti, - 'wl_notificationtimestamp' => '0' + 'wl_notificationtimestamp' => $dbw->timestampOrNull(), + 'wl_lastvisitedrevision' => 0 ), $fname ); # the following code compensates the new behaviour, introduced by the enotif patch, # that every single watched page needs now to be listed in watchlist # namespace:page and namespace_talk:page need separate entries: create them - $dbw->replace( 'watchlist', array(array('wl_user', 'wl_namespace', 'wl_title', 'wl_notificationtimestamp')), + $dbw->replace( 'watchlist', array(array('wl_user', 'wl_namespace', 'wl_title', 'wl_notificationtimestamp', 'wl_lastvisitedrevision' )), array( 'wl_user' => $this->id, 'wl_namespace' => ($this->ns | 1 ), 'wl_title' => $this->ti, - 'wl_notificationtimestamp' => '0' + 'wl_notificationtimestamp' => $dbw->timestampOrNull(), + 'wl_lastvisitedrevision' => 0 ), $fname ); global $wgMemc; @@ -93,8 +88,11 @@ } function removeWatch() { + global $wgRemoveWatchedArticleAndTalkPageTogether; + $fname = 'WatchedItem::removeWatch'; + if ($wgRemoveWatchedArticleAndTalkPageTogether) { $dbw =& wfGetDB( DB_MASTER ); $dbw->delete( 'watchlist', array( @@ -115,6 +113,16 @@ 'wl_title' => $this->ti ), $fname ); + } else { + $dbw =& wfGetDB( DB_MASTER ); + $dbw->delete( 'watchlist', + array( + 'wl_user' => $this->id, + 'wl_namespace' => $this->ns, + 'wl_title' => $this->ti + ), $fname + ); + } if ( $dbw->affectedRows() ) { global $wgMemc; @@ -128,39 +136,61 @@ /** * @static */ - function duplicateEntries( $ot, $nt ) { - $fname = "WatchedItem::duplicateEntries"; + function duplicateEntriesNs( $ot, $nt, $talkns ) { + $fname = "WatchedItem::duplicateEntriesNs"; global $wgMemc, $wgDBname; + + if ( $talkns ) { + $oldnamespace = $ot->getNamespace() | 1; + $newnamespace = $nt->getNamespace() | 1; + } else { $oldnamespace = $ot->getNamespace() & ~1; $newnamespace = $nt->getNamespace() & ~1; + } $oldtitle = $ot->getDBkey(); $newtitle = $nt->getDBkey(); $dbw =& wfGetDB( DB_MASTER ); $watchlist = $dbw->tableName( 'watchlist' ); - $res = $dbw->select( 'watchlist', 'wl_user', - array( 'wl_namespace' => $oldnamespace, 'wl_title' => $oldtitle ), + $res = $dbw->select( 'watchlist', + array( 'wl_user', + 'wl_notificationtimestamp', + 'wl_lastvisitedrevision' + ), + array( 'wl_namespace' => $oldnamespace, + 'wl_title' => $oldtitle + ), $fname, 'FOR UPDATE' ); # Construct array to replace into the watchlist $values = array(); - while ( $s = $dbw->fetchObject( $res ) ) { + if ( $s = $dbw->fetchObject( $res ) ) { $values[] = array( 'wl_user' => $s->wl_user, 'wl_namespace' => $newnamespace, - 'wl_title' => $newtitle + 'wl_title' => $newtitle, + 'wl_notificationtimestamp' => $s->wl_notificationtimestamp, + 'wl_lastvisitedrevision' => $s->wl_lastvisitedrevision ); - } + $dbw->freeResult( $res ); # Perform replace # Note that multi-row replace is very efficient for MySQL but may be inefficient for # some other DBMSes, mostly due to poor simulation by us - $dbw->replace( 'watchlist', array(array( 'wl_user', 'wl_namespace', 'wl_title')), $values, $fname ); + $dbw->replace( 'watchlist', array(array( 'wl_user', 'wl_namespace', 'wl_title' )), $values, $fname ); + } return true; } + function duplicateEntries( $ot, $nt ) { + # duplicate watchlist entries for the target page + # When using ENotif, talkpages have distinct watchlist entries + # existing talkpage entries in the watchlist will be moved, too + WatchedItem::duplicateEntriesNs( $ot, $nt, false ); + WatchedItem::duplicateEntriesNs( $ot, $nt, true ); + } } Index: includes/templates/Userlogin.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/includes/templates/Userlogin.php,v retrieving revision 1.11 diff -u -b -r1.11 Userlogin.php Index: languages/Language.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/languages/Language.php,v retrieving revision 1.501 diff -u -b -r1.501 Language.php --- languages/Language.php 27 Apr 2005 22:41:35 -0000 1.501 +++ languages/Language.php 28 Apr 2005 20:10:33 -0000 @@ -83,7 +83,7 @@ 'enotifminoredits' => 0, 'enotifrevealaddr' => 0, 'shownumberswatching' => 1, - 'rcusemodstyle' => 1, + 'rccurrevonly' => 0, 'showupdated' => 1, 'fancysig' => 0, 'externaleditor' => 0, @@ -158,7 +158,7 @@ 'enotifminoredits', 'enotifrevealaddr', 'shownumberswatching', - 'rcusemodstyle', + 'rccurrevonly', 'showupdated', 'fancysig', 'externaleditor', @@ -287,7 +287,7 @@ 'tog-enotifminoredits' => 'Send me an email also for minor edits of pages (which usually do not trigger notification mails)', 'tog-enotifrevealaddr' => 'Reveal my email address in notification mails (when I change a page, it allows watching users to reply quickly to me)', 'tog-shownumberswatching' => 'Show the number of watching users (in recent changes view, watchlist and article page footers)', -'tog-rcusemodstyle' => 'Show recent changes in UseMod style: only the most recent change of any page is listed.', +'tog-rccurrevonly' => 'Show only the current revision of pages in recent changes view.', 'tog-showupdated' => 'Show update marker ', 'tog-fancysig' => 'Raw signatures (without automatic link)', 'tog-externaleditor' => 'Use external editor by default', @@ -452,6 +452,11 @@ 'retrievedfrom' => "Retrieved from \"$1\"", 'newmessages' => "You have $1.", 'newmessageslink' => 'new messages', +'newmsg' => 'You have new messages on your $1.', +'newmsg_user' => 'user', +'newmsg_usertalk' => 'discussion', +'newmsg_page' => ' page', +'newmsg_and' => ' and ', 'editsection'=>'edit', 'toc' => 'Table of contents', 'showtoc' => 'show', @@ -602,34 +607,30 @@ 'nosuchusershort' => "There is no user by the name \"$1\". Check your spelling.", 'wrongpassword' => 'The password you entered is incorrect (or missing). Please try again.', 'mailmypassword' => 'Mail me a temporary password', -'mailmypasswordauthent' => 'Mail me a temporary password', -'passwordremindermailsubject' => "Email address authentication and temporary login password from {{SITENAME}}", +'passwordremindermailsubject' => "Email address confirmation and temporary login password from {{SITENAME}}", 'passwordremindermailbody' => "Someone, probably you from IP address $1, requested that we send you a temporary one-time login password for {{SITENAME}}. -This mail is also be sent for the purpose of authentication of your email address. +This mail is also be sent for the purpose of confirmation of your email address. The password for user \"$2\" is now \"$4\". You can now log in with this temporary password, which is valid for only one login. -You may wish to keep using your old password if you remember it or to set a new one. +You can also use your old password, if you remember it, as is is still valid. {{SERVER}}{{localurl:Special:Userlogin|wpName=$3&wpPassword=$4&returnto=Special:Preferences}}", 'noemail' => "There is no e-mail address recorded for user \"$1\".", 'passwordsent' => "A temporary password has been sent to the e-mail address registered for \"$1\". Please log in again after you receive it.", -'passwordsentforemailauthentication' - => "A temporary password has been sent to the e-mail address newly -registered for \"$1\". -Please re-login with that for authentication purposes.", 'loginend' => ' ', 'mailerror' => "Error sending mail: $1", 'acct_creation_throttle_hit' => 'Sorry, you have already created $1 accounts. You can\'t make any more.', -'emailauthenticated' => 'Your email address was authenticated on $1.', -'emailnotauthenticated' => 'Your email address is not yet authenticated and the advanced email features are disabled until authentication (d.u.a.).', 'emailconfirmlink' => 'Confirm your e-mail address', +'emailconfirmed' => 'Your email address $1 was confirmed on $2.', +'emailnotconfirmed' => 'Your email address is not yet confirmed. Therefore, the advanced email features are disabled.
+You can confirm the address by following the confirmation link, which the wiki can or has sent you.', 'invalidemailaddress' => 'The email address cannot be accepted as it appears to have an invalid format. Please enter a well-formatted address or empty that field.', -'disableduntilauthent' => '(d.u.a.)', +'disableduntilconfirmation' => '(disabled)', 'disablednoemail' => '(disabled; no email address)', # Edit page toolbar @@ -892,6 +893,7 @@ 'servertime' => 'Server time', 'guesstimezone' => 'Fill in from browser', 'emailflag' => 'Disable e-mail from other users', +'enotifnewpages' => 'Send me an email when a new page is created', 'defaultns' => 'Search in these namespaces by default:', 'default' => 'default', 'files' => 'Files', @@ -940,7 +942,13 @@ 'rchide' => "in $4 form; $1 minor edits; $2 secondary namespaces; $3 multiple edits.", 'rcliu' => "; $1 edits from logged in users", 'diff' => 'diff', +'diff_tooltiptext' => 'Show difference between this revision and the previous revision of ', +'diff-to-lvr' => 'last seen', +'diff-to-lvr_tooltiptext' => 'Show difference between this revision and the last visited revision of ', +'lvr' => 'last seen', +'lvr_tooltiptext' => 'This is the last visited revision of ', 'hist' => 'hist', +'hist_tooltiptext' => 'Show history of ', 'hide' => 'hide', 'show' => 'show', 'tableform' => 'table', @@ -1276,16 +1284,19 @@ 'email_notification_reset' => 'Reset all notification flags (set their status to "visited")', 'email_notification_newpagetext'=> 'This is a new page.', 'email_notification_to' => '$WATCHINGUSERNAME_QP <$WATCHINGUSEREMAILADDR>', -'email_notification_subject' => '{{SITENAME}} page $PAGETITLE has been changed by $PAGEEDITOR', +'email_notification_subject' => '{{SITENAME}} page $PAGETITLE has been $CHANGEDORCREATED by $PAGEEDITOR', +'changed' => 'changed', +'created' => 'created', 'email_notification_lastvisitedrevisiontext' => 'See {{SERVER}}{{localurl:$PAGETITLE_RAWURL|diff=0&oldid=$OLDID}} for all changes since your last visit.', 'email_notification_body' => 'Dear $WATCHINGUSERNAME, -the {{SITENAME}} page $PAGETITLE has been changed on $PAGEEDITDATE by $PAGEEDITOR, +the {{SITENAME}} page $PAGETITLE has been $CHANGEDORCREATED on $PAGEEDITDATE by $PAGEEDITOR, see {{SERVER}}{{localurl:$PAGETITLE_RAWURL}} for the current version. $NEWPAGE Editor\'s summary: $PAGESUMMARY $PAGEMINOREDIT + Contact the editor: mail {{SERVER}}{{localurl:Special:Emailuser|target=$PAGEEDITOR_RAWURL}} wiki {{SERVER}}{{localurl:User:$PAGEEDITOR_RAWURL}} Index: languages/LanguageDe.php =================================================================== RCS file: /cvsroot/wikipedia/phase3/languages/LanguageDe.php,v retrieving revision 1.111 diff -u -b -r1.111 LanguageDe.php --- languages/LanguageDe.php 10 Apr 2005 19:45:50 -0000 1.111 +++ languages/LanguageDe.php 28 Apr 2005 20:10:34 -0000 @@ -111,12 +111,13 @@ 'special_version_prefix' => '', 'special_version_postfix' => '', # User toggles +'tog-hover' => 'Tooltips anzeigen', "tog-underline" => "Verweise unterstreichen", "tog-highlightbroken" => "Verweise auf leere Themen hervorheben", "tog-justify" => "Text als Blocksatz", "tog-hideminor" => "Keine kleinen Änderungen in Letzte Änderungen anzeigen", "tog-usenewrc" => "Erweiterte letzte Änderungen (nicht für alle Browser geeignet)", -"tog-numberheadings" => "Überschriften automatisch numerieren", +"tog-numberheadings" => "Überschriften automatisch nummerieren", "tog-showtoolbar" => "Editier-Werkzeugleiste anzeigen", "tog-editondblclick" => "Seiten mit Doppelklick bearbeiten (JavaScript)", "tog-editsection" => "Links zum Bearbeiten einzelner Absätze anzeigen", @@ -127,7 +128,16 @@ "tog-watchdefault" => "Neue und geänderte Seiten beobachten", "tog-minordefault" => "Alle Änderungen als geringfügig markieren", "tog-previewontop" => "Vorschau vor dem Editierfenster anzeigen", +'tog-previewonfirst' => 'Vorschau beim ersten Editieren anzeigen', "tog-nocache" => "Seitencache deaktivieren", +'tog-enotifwatchlistpages' => 'Benachrichtigungsmails für Seitenänderungen (eventuell noch offene Benachrichtungen müssen manuell in der Beobachtungsliste gelöscht werden)', +'tog-enotifusertalkpages' => 'Benachrichtigungsmails für Änderungen an Ihren Benutzerseiten (eventuell noch offene Benachrichtungen müssen manuell in der Beobachtungsliste gelöscht werden)', +'tog-enotifminoredits' => 'Benachrichtigungsmails auch für kleine Seitenänderungen (die sonst keine Benachrichtigungsmail auslösen)', +'tog-enotifrevealaddr' => 'Ihre E-Mail-Adresse wird in Benachrichtigungsmails gezeigt (wenn Sie eine Seite änderen; das ermöglicht anderen, Ihnen direkt zu antworten)', +'tog-shownumberswatching' => 'Zeige die Anzahl seitenbeobachtender Benutzer (in Letzte Änderungen, Beobachtungsliste und Artikelseiten)', +'tog-rccurrevonly' => 'Zeige nur die letzte Seitenversion in Letzte Änderungen.', +'tog-showupdated' => 'Zeige bei beobachteten Seiten mit ungesehenen Änderungen die Markierung ', +'tog-fancysig' => 'Einfache Unterschrift (Spitzname ohne Link)', # Dates 'sunday' => "Sonntag", 'monday' => "Montag", @@ -373,6 +383,8 @@ "login" => "Anmelden", "loginprompt" => "Um sich bei {{SITENAME}} anmelden zu können, müssen Cookies aktiviert sein.", "userlogin" => "Anmelden", +'disabled_on_this_wiki' => '
Diese Funktion ist bei diesem Wiki dauerhaft abeschaltet. +Durch die automatische Anmeldung beim Benutzerkonto sind eigene Benutzer-Anmeldung oder -Abmeldung nicht erforderlich.
', "logout" => "Abmelden", "userlogout" => "Abmelden", "notloggedin" => "Nicht angemeldet", @@ -380,28 +392,52 @@ "createaccountmail" => "über eMail", "badretype" => "Die beiden Passwörter stimmen nicht überein.", "userexists" => "Dieser Benutzername ist schon vergeben. Bitte wählen Sie einen anderen.", -"youremail" => "Ihre E-Mail", +"youremail" => "Ihre E-Mail-Adresse**", "yournick" => "Ihr \"Spitzname\" (zum \"Unterschreiben\")", -"yourrealname" => "Ihr echter Name (keine Pflicht)", +"yourrealname" => "Ihr echter Name (keine Pflichtangabe)*", "emailforlost" => "Falls Sie Ihr Passwort vergessen haben, kann Ihnen ein neues an Ihre E-Mail-Adresse gesendet werden.", +'prefs-help-email' => '** E-Mail-Adresse (optional): Erlaubt andern, Sie über Ihre Benutzerseiten zu kontaktieren, ohne dass Sie Ihre E-Mail-Adresse offenbaren müssen. +Für den Fall, dass Sie Ihr Passwort vergessen haben, kann Ihnen so ein temporäres Einmal-Passwort gesendet werden.', +'prefs-help-email-enotif' => 'An diese Adresse werden auch die Benachrichtigungsmails geschickt, sofern Sie das eingeschaltet haben.', +'prefs-help-realname' => '* Echter Name (optional): für anerkennende Nennungen Ihres Namens im Zusammenhang mit Ihren Beiträgen.', +'prefs-help-userdata' => '* Echter Name (optional): für anerkennende Nennungen Ihres Namens im Zusammenhang mit Ihren Beiträgen.
+* E-Mail (optional): Erlaubt andern, Sie über Ihre Benutzerseiten zu kontaktieren, ohne dass Sie Ihre E-Mail-Adresse offenbaren müssen. +Für den Fall, dass Sie Ihr Passwort vergessen haben, kann Ihnen so ein neues, temporäres gesendet werden.', "loginerror" => "Fehler bei der Anmeldung", "noname" => "Sie müssen einen Benutzernamen angeben.", "loginsuccesstitle" => "Anmeldung erfolgreich", "loginsuccess" => "Sie sind jetzt als \"$1\" bei {{SITENAME}} angemeldet.", "nosuchuser" => "Der Benutzername \"$1\" existiert nicht. Überprüfen Sie die Schreibweise, oder melden Sie sich als neuer Benutzer an.", -"wrongpassword" => "Das Passwort ist falsch. Bitte versuchen Sie es erneut.", -"mailmypassword" => "Ein neues Passwort schicken", -"passwordremindertitle" => "{{SITENAME}} Passwort", -"passwordremindertext" => "Jemand (IP-Adresse $1) -hat um ein neues Passwort für die Anmeldung bei {{SITENAME}} gebeten. +"wrongpassword" => "Das Passwort ist falsch (oder fehlt). Bitte versuchen Sie es erneut.", +"mailmypassword" => "Ein neues (temporäres) Passwort schicken", +'mailmypasswordauthent' => 'Ein neues (temporäres) Passwort schicken, auch für Authentifizierung', +'passwordremindermailsubject' => "E-Mail-Adressenauthentifizierung und temporäres Passwort für {{SITENAME}}", +'passwordremindermailbody' => "Jemand, vielleicht Sie, hat von IP-Adresse $1 +um ein temporäres Einmal-Passwort für die Anmeldung bei {{SITENAME}} gebeten. + Das Passwort für Benutzer \"$2\" lautet nun \"$3\". -Sie sollten sich jetzt anmelden und Ihr Passwort ändern.", + +Bitte melden Sie sich nun mit diesem temporären Passwort an, das gleichzeitig der Authentifizierung +Ihrer E-Mail-Adresse dient. Für weitere Anmeldungen verwenden Sie bitte wieder Ihr altes Passwort. +Alternativ können Sie auch ein neues eintragen, zum Beispiel, wenn Sie das alte vergessen haben., + +{{SERVER}}{{localurl:Special:Userlogin|wpName=$3&wpPassword=$4&returnto=Special:Preferences}}", "noemail" => "Benutzer \"$1\" hat keine E-Mail-Adresse angegeben.", -"passwordsent" => "Ein neues Passwort wurde an die E-Mail-Adresse von Benutzer \"$1\" gesendet. -Bitte melden Sie sich an, sobald Sie es erhalten.", +"passwordsent" => "Ein temporäres Passwort wurde an die E-Mail-Adresse von Benutzer \"$1\" gesendet. +Bitte melden Sie sich damit an, sobald Sie es erhalten.", +'passwordsentforemailauthentication' + => "Ein temporäres Passwort wurde an die gerade neu eingetragene E-Mail-Adresse des Benutzers \"$1\" gesendet. +Bitte melden Sie sich damit an, um die Adressauthentifizierung durchzuführen.", "loginend" => " ", "mailerror" => "Fehler beim Senden von Mail: $1", +'acct_creation_throttle_hit' => 'Sie haben schon $1 Benutzerkonten und können jetzt keine weiteren mehr anlegen.', +'emailauthenticated' => 'Ihre E-Mail-Adresse $1 wurde am $2 authentifiziert.', +'emailnotauthenticated' => 'Ihre E-Mail-Adresse ist noch nicht authentifiziert und die erweiterten E-Mailfunktionen sind bis zur Authentifizierung ohne Funktion (aus).
+Für die Authentifizierung melden Sie sich bitte mit dem per E-Mail geschickten temporären Passwort an, oder fordern Sie auf der Anmeldeseite ein neues an.', +'invalidemailaddress' => 'Die E-Mail-Adresse wurde nicht akzeptiert, da sie ein ungültiges Format aufzuweisen scheint. Bitte geben Sie eine Adresse in einem gültigen Format ein, oder leeren Sie das Feld.', +'disableduntilauthent' => '(aus)', +'disablednoemail' => '(aus; keine E-Mail-Adresse)', # Edit pages # @@ -437,6 +473,7 @@ '''Beachten Sie:''' Nach dem Speichern müssen Sie ihrem Browser sagen, die neue Version zu laden: '''Mozilla:''' Klick auf ''Neu laden''(oder ''Strg-R''), '''IE / Opera:''' ''Strg-F5'', '''Safari:''' ''Cmd-r'', '''Konqueror''' ''Strg-R''.", 'userjspreview' => "== Vorschau Ihres Benutzer-Javascript. == '''Beachten Sie:''' Nach dem Speichern müssen Sie ihrem Browser sagen, die neue Version zu laden: '''Mozilla:''' Klick auf ''Neu laden''(oder ''Strg-R''), '''IE / Opera:''' ''Strg-F5'', '''Safari:''' ''Cmd-r'', '''Konqueror''' ''Strg-R''.", +'clearyourcache' => "'''Beachten Sie:''' Nach dem Speichern müssen Sie ihrem Browser sagen, die neue Version zu laden: '''Mozilla:''' Klick auf ''Neu laden''(oder ''Strg-R''), '''IE / Opera:''' ''Strg-F5'', '''Safari:''' ''Cmd-r'', '''Konqueror''' ''Strg-R''.", 'usercssjsyoucanpreview' => "Tipp: Benutzen Sie den Vorschau-Button, um Ihr neues css/js vor dem Speichern zu testen.", "updated" => "(Geändert)", "note" => "Hinweis: ", @@ -483,8 +520,10 @@ 'nextrevision' => '←Nächstjüngere Version', 'previousrevision' => 'Nächstältere Version→', "cur" => "Aktuell", +'cur_tooltiptext' => 'Zeige Differenz zwischen dieser und aktueller Version von ', "next" => "Nächste", -"last" => "Letzte", +"last" => "Vorherige", +'last_tooltiptext' => 'Zeige Differenz zwischen dieser und vorheriger Version von ', "orig" => "Original", "histlegend" => "Diff Auswahl: Die Boxen der gewünschten Versionen markieren und 'Enter' drücken oder den Button unten klicken/alt-v.
@@ -542,7 +581,8 @@ # "preferences" => "Einstellungen", "prefsnologin" => "Nicht angemeldet", -"prefsnologintext" => "Sie müssen [[Spezial:Userlogin|angemeldet]] +"prefsnologintext" => "Sie müssen angemeldet sein, um Ihre Einstellungen zu ändern.", "prefslogintext" => "Sie sind angemeldet als \"$1\". Ihre interne ID-Nummer ist $2.", @@ -562,7 +602,7 @@ "oldpassword" => "Altes Passwort", "newpassword" => "Neues Passwort", "retypenew" => "Neues Passwort (nochmal)", -"textboxsize" => "Textfeld-Grösse", +"textboxsize" => "Textfeld-Größe", "rows" => "Zeilen", "columns" => "Spalten", "searchresultshead" => "Suchergebnisse", @@ -579,6 +619,7 @@ "servertime" => "Aktuelle Zeit auf dem Server", "guesstimezone" => "Einfügen aus dem Browser", "emailflag" => "Keine E-Mail von anderen Benutzern erhalten", +'enotifnewpages' => 'Sende mir eine Benachrichtigungsmail, wenn jemand eine neue Seite anlegt.', "defaultns" => "In diesen Namensräumen soll standardmäßig gesucht werden:", # Recent changes @@ -595,7 +636,13 @@ "rclistfrom" => "Zeige neue Änderungen seit $1", "rclinks" => "Zeige die letzten $1 Änderungen; zeige die letzten $2 Tage.", "diff" => "Unterschied", +'diff_tooltiptext' => 'Zeige Differenz zwischen dieser und der vorherigen Version von ', +'diff-to-lvr' => 'letzte', +'diff-to-lvr_tooltiptext' => 'Zeige Differenz zwischen dieser und der zuletzt gesehenen Version von ', +'lvr' => 'lvrd', +'lvr_tooltiptext' => 'Das ist die zuletzt gesehene Version von ', "hist" => "Versionen", +"hist_tooltiptext" => "Zeige ältere Versionen von ", "hide" => "Ausblenden", "show" => "Einblenden", "tableform" => "Tabelle", @@ -603,6 +650,7 @@ "nchanges" => "$1 Änderungen", "minoreditletter" => "M", "newpageletter" => "N", +'number_of_watching_users_pageview' => '[$1 Benutzer beobachten diese Seite]', # Upload @@ -613,7 +661,8 @@ "reupload" => "Erneut hochladen", "reuploaddesc" => "Zurück zur Hochladen-Seite.", "uploadnologin" => "Nicht angemeldet", -"uploadnologintext" => "Sie müssen [[Spezial:Userlogin|angemeldet sein]] +"uploadnologintext" => "Sie müssen angemeldet sein um Dateien hochladen zu können.", "uploadfile" => "Datei hochladen", "uploaderror" => "Fehler beim Hochladen", @@ -763,7 +812,8 @@ # Email this user # "mailnologin" => "Sie sind nicht angemeldet.", -"mailnologintext" => "Sie müssen [[Spezial:Userlogin|angemeldet sein]] +"mailnologintext" => "Sie müssen angemeldet sein und eine gültige E-Mail-Adresse haben, um anderen Benutzern E-Mail zu schicken.", "emailuser" => "E-Mail an diesen Benutzer", "emailpage" => "E-Mail an Benutzer", @@ -787,7 +837,8 @@ "watchlistsub" => "(für Benutzer \"$1\")", "nowatchlist" => "Sie haben keine Einträge auf Ihrer Beobachtungsliste.", "watchnologin" => "Sie sind nicht angemeldet", -"watchnologintext" => "Sie müssen [[Spezial:Userlogin|angemeldet]] +"watchnologintext" => "Sie müssen angemeldet sein, um Ihre Beobachtungsliste zu bearbeiten.", "addedwatch" => "Zur Beobachtungsliste hinzugefügt", "addedwatchtext" => "Der Artikel \"$1\" wurde zu Ihrer "($1 Artikel werden beobachtet (ohne Diskussionsseiten); $2 Artikel im eingestellten Zeitraum bearbeitet; $3... komplette Liste zeigen und bearbeiten.)", -"watchmethod-recent" => "überprüfen der letzten Bearbeitungen für die Beobachtungsliste", -"watchmethod-list" => "überprüfen der Beobachtungsliste nach letzten Bearbeitungen", +"watchmethod-recent" => "Überprüfen der letzten Bearbeitungen für die Beobachtungsliste", +"watchmethod-list" => "Überprüfen der Beobachtungsliste nach letzten Bearbeitungen", "removechecked" => "Markierte Einträge löschen", "watchlistcontains" => "Ihre Beobachtungsliste enthält $1 Seiten.", "watcheditlist" => "Hier ist eine alphabetische Liste der von Ihnen beobachteten Seiten. Markieren Sie die Seiten die Sie von der Beobachtungsliste löschen wollen und betätigen Sie den 'markierte Einträge löschen' Knopf am Ende der Seite.", "removingchecked" => "Wunschgemäß werden die Einträge aus der Beobachtungsliste entfernt...", "couldntremove" => "Der Eintrag '$1' kann nicht gelöscht werden...", -"iteminvalidname" => "Ploblem mit dem Eintrag '$1', ungültiger Name...", +"iteminvalidname" => "Problem mit dem Eintrag '$1', ungültiger Name...", 'wlnote' => 'Es folgen die letzten $1 Änderungen der letzten $2 Stunden.', 'wlshowlast' => 'Zeige die letzen $1 Stunden $2 Tage $3', 'wlsaved' => 'Dies ist eine gespeicherte Version Ihrer Beobachtungsliste.', @@ -822,6 +873,38 @@ 'wlshow' => 'Zeige ', 'wlhide' => 'Verstecke ', +'updatedmarker' => ' (geändert) ', +'updatedmarker_tooltiptext' => 'Zeige Differenz zwischen aktueller und zuletzt gesehener Version von ', +'email_notification_mailer' => '{{SITENAME}} Benachrichtigungsdienst', +'email_notification_infotext' => "'''E-Mail-Benachrichtigungen eingeschaltet.''' +Sie erhalten Benachrichtigungsmails, wenn jemand eine Seite ändert, die Sie beobachten.", +'email_notification_reset' => 'Alle Benachrichtigungsmarker zurücksetzen ("alles gesehen")', +'email_notification_newpagetext'=> 'Das ist eine neue Seite.', +'email_notification_to' => '$WATCHINGUSERNAME_QP <$WATCHINGUSEREMAILADDR>', +'email_notification_subject' => 'Die {{SITENAME}} Seite $PAGETITLE wurde von $PAGEEDITOR $CHANGEDORCREATED', +'changed' => 'geändert', +'created' => 'neu angelegt', +'email_notification_lastvisitedrevisiontext' => '{{SERVER}}{{localurl:$PAGETITLE_RAWURL|diff=0&oldid=$OLDID}} zeigt alle Änderungen auf einen Blick.', +'email_notification_body' => 'Liebe/r $WATCHINGUSERNAME, + +die {{SITENAME}} Seite $PAGETITLE wurde von $PAGEEDITOR am $PAGEEDITDATE $CHANGEDORCREATED, +die aktuelle Version ist {{SERVER}}{{localurl:$PAGETITLE_RAWURL}}. + +$NEWPAGE + +Zusammenfassung des Editors: $PAGESUMMARY $PAGEMINOREDIT +Kontakt zum Editor: +Mail {{SERVER}}{{localurl:Special:Emailuser|target=$PAGEEDITOR_RAWURL}} +Wiki {{SERVER}}{{localurl:User:$PAGEEDITOR_RAWURL}} + +Es werden solange keine weiteren Benachrichtigungsmails gesendet, bis Sie die Seite wieder besuchen. +Auf Ihrer Beobachtungsseite können Sie alle Benachrichtigungsmarker zusammen zurücksetzen. + + Ihr freundliches {{SITENAME}} Benachrichtigungssystem + +--- +Ihre Beobachtungsliste {{SERVER}}{{localurl:Special:Watchlist|magic=yes}} +Hilfe zur Benutzung gibt {{SERVER}}{{localurl:WikiHelpdesk}}', # Delete/protect/revert # @@ -970,7 +1053,7 @@ "movearticle" => "Artikel verschieben", "movenologin" => "Sie sind nicht angemeldet", "movenologintext" => "Sie müssen ein registrierter Benutzer und -[[Special:Userlogin|angemeldet]] sein, +angemeldet sein, um eine Seite zu verschieben.", "newtitle" => "Zu neuem Titel", "movepagebtn" => "Artikel verschieben", @@ -1167,6 +1250,7 @@ 'speciallogtitlelabel' => 'Titel: ', 'passwordtooshort' => 'Ihr Passwort ist zu kurz. Es muss mindestens $1 Zeichen lang sein.', +'imagemaxsize' => 'Bildgrößenbegrenzung auf Bildbeschreibungsseiten: ', ); class LanguageDe extends LanguageUtf8 { Index: maintenance/tables.sql =================================================================== RCS file: /cvsroot/wikipedia/phase3/maintenance/tables.sql,v retrieving revision 1.53 diff -u -b -r1.53 tables.sql --- maintenance/tables.sql 26 Apr 2005 19:57:55 -0000 1.53 +++ maintenance/tables.sql 28 Apr 2005 20:10:35 -0000 @@ -11,11 +11,11 @@ user_password tinyblob NOT NULL default '', user_newpassword tinyblob NOT NULL default '', user_email tinytext NOT NULL default '', - user_emailauthenticationtimestamp varchar(14) binary NOT NULL default '0', + user_emailnotificationfornewpages tinyint(1) NOT NULL default '0', user_options blob NOT NULL default '', user_touched char(14) binary NOT NULL default '', user_token char(32) binary NOT NULL default '', - user_email_authenticated CHAR(14) BINARY, + user_email_confirmed CHAR(14) BINARY, user_email_token CHAR(32) BINARY, user_email_token_expires CHAR(14) BINARY, @@ -31,14 +31,16 @@ UNIQUE KEY ur_user (ur_user) ); --- The following table is no longer needed with Enotif >= 2.00 --- Entries for newtalk on user_talk page are handled like in the watchlist table --- CREATE TABLE /*$wgDBprefix*/user_newtalk ( --- user_id int(5) NOT NULL default '0', --- user_ip varchar(40) NOT NULL default '', --- INDEX user_id (user_id), --- INDEX user_ip (user_ip) --- ); +-- Entries for newtalk on user_talk page are +-- handled in table user_newtalk for efficient memcaching +-- but are also handled as entries in the watchlist table for email notifications +CREATE TABLE /*$wgDBprefix*/user_newtalk ( + user_id int(5) NOT NULL default '0', + user_ip varchar(40) NOT NULL default '', + INDEX user_id (user_id), + INDEX user_ip (user_ip) +); + CREATE TABLE /*$wgDBprefix*/page ( -- Identifiers: @@ -268,6 +270,7 @@ wl_namespace tinyint(2) unsigned NOT NULL default '0', wl_title varchar(255) binary NOT NULL default '', wl_notificationtimestamp varchar(14) binary NOT NULL default '0', + wl_lastvisitedrevision int(10) unsigned NOT NULL default '0', UNIQUE KEY (wl_user, wl_namespace, wl_title), KEY namespace_title (wl_namespace,wl_title) ); @@ -368,9 +371,6 @@ ); - - - -- Hold group name and description CREATE TABLE /*$wgDBprefix*/`group` ( group_id int(5) unsigned NOT NULL auto_increment, Index: maintenance/updaters.inc =================================================================== RCS file: /cvsroot/wikipedia/phase3/maintenance/updaters.inc,v retrieving revision 1.48 diff -u -b -r1.48 updaters.inc --- maintenance/updaters.inc 25 Apr 2005 18:38:41 -0000 1.48 +++ maintenance/updaters.inc 28 Apr 2005 20:10:35 -0000 @@ -159,11 +159,18 @@ if( $wgDatabase->fieldExists( 'watchlist', 'wl_notificationtimestamp' ) ) { echo "ENOTIF: The watchlist table is already set up for email notification.\n"; } else { - echo "ENOTIF: Adding wl_notificationtimestamp field for email notification management."; + echo "ENOTIF: Adding wl_notificationtimestamp field for email notification management.\n"; /* ALTER TABLE watchlist ADD (wl_notificationtimestamp varchar(14) binary NOT NULL default '0'); */ dbsource( "maintenance/archives/patch-email-notification.sql", $wgDatabase ); echo "ok\n"; } + if( $wgDatabase->fieldExists( 'watchlist', 'wl_lastvisitedrevision' ) ) { + echo "ENOTIF: The watchlist table is already set up for last-visited-revision (lvr) management.\n"; + } else { + echo "ENOTIF: Adding wl_lastvisitedrevision field for last-visited-revision (lvr) management.\n"; + dbsource( "maintenance/archives/patch-last-visited-revision.sql", $wgDatabase ); + echo "ok\n"; + } } function do_copy_newtalk_to_watchlist() { @@ -187,7 +194,7 @@ array('wl_user' => 0, 'wl_namespace' => NS_USER_TALK, 'wl_title' => $wluser->user_ip, - 'wl_notificationtimestamp' => '19700101000000' + 'wl_notificationtimestamp' => '0' ), 'updaters.inc::do_watchlist_update2' ); echo 'ENOTIF: ====> watchlist: user_id=0 '.$wluser->user_ip."\n"; @@ -199,17 +206,19 @@ array('wl_user' => $user->getID(), 'wl_namespace' => NS_USER_TALK, 'wl_title' => $user->getName(), - 'wl_notificationtimestamp' => '19700101000000' + 'wl_notificationtimestamp' => '0' ), 'updaters.inc::do_watchlist_update3' ); echo 'ENOTIF: ====> watchlist: user_id='.$user->getID().' '.$user->getName()."\n"; } } echo "ENOTIF: The watchlist table has got the former user_newtalk entries.\n"; - dbsource( "maintenance/archives/patch-drop-user_newtalk.sql", $wgDatabase ); - echo "ENOTIF: Deleting the user_newtalk table as its entries are now in the watchlist table.\n"; + ### dbsource( "maintenance/archives/patch-drop-user_newtalk.sql", $wgDatabase ); + ### echo "ENOTIF: Deleting the user_newtalk table as its entries are now in the watchlist table.\n"; } else { - echo "ENOTIF: No user_newtalk table found. Nothing to convert to watchlist table entries.\n"; + echo "ENOTIF: No user_newtalk table found. Creating table user_newtalk.\n"; + dbsource( "maintenance/archives/patch-create-user_newtalk.sql", $wgDatabase ); + echo "ok\n"; } } @@ -223,6 +232,14 @@ } else { echo "...user table does not contain old email authentication field.\n"; } + if( $wgDatabase->fieldExists( 'user', 'user_emailnotificationfornewpages' ) ) { + echo "ENOTIF: The user table is already set up for email notification for new pages.\n"; + } else { + echo "ENOTIF: Adding user_emailnotificationfornewpages field."; + ### ALTER TABLE /*$wgDBprefix*/user ADD (user_emailnotificationfornewpages tinyint(1) NOT NULL default '0'); + dbsource( "maintenance/archives/patch-email-notification-fornewpages.sql", $wgDatabase ); + echo "ok\n"; + } } # Assumes that the group table has been added.