Merge "Improve docs for Title::getInternalURL/getCanonicalURL"
[lhc/web/wiklou.git] / includes / jobqueue / jobs / ClearWatchlistNotificationsJob.php
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
17 *
18 * @file
19 * @ingroup JobQueue
20 */
21
22 use MediaWiki\MediaWikiServices;
23
24 /**
25 * Job for clearing all of the "last viewed" timestamps for a user's watchlist, or setting them all
26 * to the same value.
27 *
28 * Job parameters include:
29 * - userId: affected user ID [required]
30 * - casTime: UNIX timestamp of the event that triggered this job [required]
31 * - timestamp: value to set all of the "last viewed" timestamps to [optional, defaults to null]
32 *
33 * @ingroup JobQueue
34 * @since 1.31
35 */
36 class ClearWatchlistNotificationsJob extends Job {
37 function __construct( Title $title, array $params ) {
38 parent::__construct( 'clearWatchlistNotifications', $title, $params );
39
40 static $required = [ 'userId', 'casTime' ];
41 $missing = implode( ', ', array_diff( $required, array_keys( $this->params ) ) );
42 if ( $missing != '' ) {
43 throw new InvalidArgumentException( "Missing parameter(s) $missing" );
44 }
45
46 $this->removeDuplicates = true;
47 }
48
49 public function run() {
50 $services = MediaWikiServices::getInstance();
51 $lbFactory = $services->getDBLoadBalancerFactory();
52 $rowsPerQuery = $services->getMainConfig()->get( 'UpdateRowsPerQuery' );
53
54 $dbw = $lbFactory->getMainLB()->getConnection( DB_MASTER );
55 $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
56 $timestamp = $this->params['timestamp'] ?? null;
57 if ( $timestamp === null ) {
58 $timestampCond = 'wl_notificationtimestamp IS NOT NULL';
59 } else {
60 $timestamp = $dbw->timestamp( $timestamp );
61 $timestampCond = 'wl_notificationtimestamp != ' . $dbw->addQuotes( $timestamp ) .
62 ' OR wl_notificationtimestamp IS NULL';
63 }
64 // New notifications since the reset should not be cleared
65 $casTimeCond = 'wl_notificationtimestamp < ' .
66 $dbw->addQuotes( $dbw->timestamp( $this->params['casTime'] ) ) .
67 ' OR wl_notificationtimestamp IS NULL';
68
69 $firstBatch = true;
70 do {
71 $idsToUpdate = $dbw->selectFieldValues(
72 'watchlist',
73 'wl_id',
74 [
75 'wl_user' => $this->params['userId'],
76 $timestampCond,
77 $casTimeCond,
78 ],
79 __METHOD__,
80 [ 'LIMIT' => $rowsPerQuery ]
81 );
82 if ( $idsToUpdate ) {
83 $dbw->update(
84 'watchlist',
85 [ 'wl_notificationtimestamp' => $timestamp ],
86 [
87 'wl_id' => $idsToUpdate,
88 // For paranoia, enforce the CAS time condition here too
89 $casTimeCond
90 ],
91 __METHOD__
92 );
93 if ( !$firstBatch ) {
94 $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
95 }
96 $firstBatch = false;
97 }
98 } while ( $idsToUpdate );
99 return true;
100 }
101 }