Index: includes/EnotifNotifyJob.php =================================================================== --- includes/EnotifNotifyJob.php (revision 47926) +++ includes/EnotifNotifyJob.php (working copy) @@ -26,7 +26,8 @@ $this->params['timestamp'], $this->params['summary'], $this->params['minorEdit'], - $this->params['oldid'] + $this->params['oldid'], + $this->params['watchers'] ); return true; } Index: includes/UserMailer.php =================================================================== --- includes/UserMailer.php (revision 47926) +++ includes/UserMailer.php (working copy) @@ -281,11 +281,43 @@ * @param $oldid (default: false) */ function notifyOnPageChange($editor, $title, $timestamp, $summary, $minorEdit, $oldid = false) { - global $wgEnotifUseJobQ; + global $wgEnotifUseJobQ, $wgEnotifWatchlist, $wgShowUpdatedMarker; - if( $title->getNamespace() < 0 ) + if ($title->getNamespace() < 0) return; + // Build a list of users to notfiy + $watchers = array(); + if ($wgEnotifWatchlist || $wgShowUpdatedMarker) { + $dbw = wfGetDB( DB_MASTER ); + list( $user ) = $dbr->tableNamesN( 'user' ); + $res = $dbw->select( array( 'watchlist' ), + array( 'wl_user' ), + array( + 'wl_title' => $title->getDBkey(), + 'wl_namespace' => $title->getNamespace(), + 'wl_user != ' . intval( $editor->getID() ), + 'wl_notificationtimestamp IS NULL', + ), __METHOD__ + ); + while ($row = $dbw->fetchObject( $res ) ) { + $watchers[] = intval( $row->wl_user ); + } + if ($watchers) { + // Update wl_notificationtimestamp for all watching users except + // the editor + $dbw->begin(); + $dbw->update( 'watchlist', + array( /* SET */ + 'wl_notificationtimestamp' => $dbw->timestamp( $timestamp ) + ), array( /* WHERE */ + 'wl_user' => $watchers + ), __METHOD__ + ); + $dbw->commit(); + } + } + if ($wgEnotifUseJobQ) { $params = array( "editor" => $editor->getName(), @@ -293,11 +325,12 @@ "timestamp" => $timestamp, "summary" => $summary, "minorEdit" => $minorEdit, - "oldid" => $oldid); + "oldid" => $oldid, + "watchers" => $watchers); $job = new EnotifNotifyJob( $title, $params ); $job->insert(); } else { - $this->actuallyNotifyOnPageChange($editor, $title, $timestamp, $summary, $minorEdit, $oldid); + $this->actuallyNotifyOnPageChange( $editor, $title, $timestamp, $summary, $minorEdit, $oldid, $watchers ); } } @@ -310,15 +343,16 @@ * * @param $editor User object * @param $title Title object - * @param $timestamp - * @param $summary - * @param $minorEdit - * @param $oldid (default: false) + * @param $timestamp string Edit timestamp + * @param $summary string Edit summary + * @param $minorEdit bool + * @param $oldid int Revision ID + * @param $watchers array of user IDs */ - function actuallyNotifyOnPageChange($editor, $title, $timestamp, $summary, $minorEdit, $oldid=false) { + function actuallyNotifyOnPageChange($editor, $title, $timestamp, $summary, $minorEdit, $oldid, $watchers) { # we use $wgPasswordSender as sender's address global $wgEnotifWatchlist; - global $wgEnotifMinorEdits, $wgEnotifUserTalk, $wgShowUpdatedMarker; + global $wgEnotifMinorEdits, $wgEnotifUserTalk; global $wgEnotifImpersonal; wfProfileIn( __METHOD__ ); @@ -363,30 +397,12 @@ if ( $wgEnotifWatchlist ) { // Send updates to watchers other than the current editor - $userCondition = 'wl_user != ' . intval( $editor->getID() ); - if ( $userTalkId !== false ) { - // Already sent an email to this person - $userCondition .= ' AND wl_user != ' . intval( $userTalkId ); - } - $dbr = wfGetDB( DB_SLAVE ); - - list( $user ) = $dbr->tableNamesN( 'user' ); - $res = $dbr->select( array( 'watchlist', 'user' ), - array( "$user.*" ), - array( - 'wl_user=user_id', - 'wl_title' => $title->getDBkey(), - 'wl_namespace' => $title->getNamespace(), - $userCondition, - 'wl_notificationtimestamp IS NULL', - ), __METHOD__ - ); - $userArray = UserArray::newFromResult( $res ); - + $userArray = UserArray::newFromIDs( $watchers ); foreach ( $userArray as $watchingUser ) { if ( $watchingUser->getOption( 'enotifwatchlistpages' ) && ( !$minorEdit || $watchingUser->getOption('enotifminoredits') ) && - $watchingUser->isEmailConfirmed() ) + $watchingUser->isEmailConfirmed() && + $watchingUser->getID() != $userTalkId ) { $this->compose( $watchingUser ); } @@ -400,31 +416,9 @@ $this->compose( $user ); } - $latestTimestamp = Revision::getTimestampFromId( $title, $title->getLatestRevID(GAID_FOR_UPDATE) ); - // Do not update watchlists if something else already did. - if ( $timestamp >= $latestTimestamp && ($wgShowUpdatedMarker || $wgEnotifWatchlist) ) { - # Mark the changed watch-listed page with a timestamp, so that the page is - # listed with an "updated since your last visit" icon in the watch list. Do - # not do this to users for their own edits. - $dbw = wfGetDB( DB_MASTER ); - $dbw->begin(); - $dbw->update( 'watchlist', - array( /* SET */ - 'wl_notificationtimestamp' => $dbw->timestamp($timestamp) - ), array( /* WHERE */ - 'wl_title' => $title->getDBkey(), - 'wl_namespace' => $title->getNamespace(), - 'wl_notificationtimestamp IS NULL', // store oldest unseen change time - 'wl_user != ' . intval( $editor->getID() ) - ), __METHOD__ - ); - $dbw->commit(); - } - $this->sendMails(); - wfProfileOut( __METHOD__ ); - } # function NotifyOnChange + } /** * @private Index: includes/UserArray.php =================================================================== --- includes/UserArray.php (revision 47926) +++ includes/UserArray.php (working copy) @@ -12,6 +12,17 @@ return $userArray; } + static function newFromIDs( $ids ) { + $ids = array_map( 'intval', (array)$ids ); // paranoia + if ( !$ids ) + // Database::select() doesn't like empty arrays + return new ArrayIterator(array()); + $dbr = wfGetDB( DB_SLAVE ); + $res = $dbr->select( 'user', '*', array( 'user_id' => $ids ), + __METHOD__ ); + return self::newFromResult( $res ); + } + protected static function newFromResult_internal( $res ) { $userArray = new UserArrayFromResult( $res ); return $userArray;