ClearWatchlistNotificationsJob.php 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. use MediaWiki\MediaWikiServices;
  22. /**
  23. * Job for clearing all of the "last viewed" timestamps for a user's watchlist, or setting them all
  24. * to the same value.
  25. *
  26. * Job parameters include:
  27. * - userId: affected user ID [required]
  28. * - casTime: UNIX timestamp of the event that triggered this job [required]
  29. * - timestamp: value to set all of the "last viewed" timestamps to [optional, defaults to null]
  30. *
  31. * @ingroup JobQueue
  32. * @since 1.31
  33. */
  34. class ClearWatchlistNotificationsJob extends Job implements GenericParameterJob {
  35. function __construct( array $params ) {
  36. parent::__construct( 'clearWatchlistNotifications', $params );
  37. static $required = [ 'userId', 'casTime' ];
  38. $missing = implode( ', ', array_diff( $required, array_keys( $this->params ) ) );
  39. if ( $missing != '' ) {
  40. throw new InvalidArgumentException( "Missing parameter(s) $missing" );
  41. }
  42. $this->removeDuplicates = true;
  43. }
  44. public function run() {
  45. $services = MediaWikiServices::getInstance();
  46. $lbFactory = $services->getDBLoadBalancerFactory();
  47. $rowsPerQuery = $services->getMainConfig()->get( 'UpdateRowsPerQuery' );
  48. $dbw = $lbFactory->getMainLB()->getConnectionRef( DB_MASTER );
  49. $ticket = $lbFactory->getEmptyTransactionTicket( __METHOD__ );
  50. $timestamp = $this->params['timestamp'] ?? null;
  51. if ( $timestamp === null ) {
  52. $timestampCond = 'wl_notificationtimestamp IS NOT NULL';
  53. } else {
  54. $timestamp = $dbw->timestamp( $timestamp );
  55. $timestampCond = 'wl_notificationtimestamp != ' . $dbw->addQuotes( $timestamp ) .
  56. ' OR wl_notificationtimestamp IS NULL';
  57. }
  58. // New notifications since the reset should not be cleared
  59. $casTimeCond = 'wl_notificationtimestamp < ' .
  60. $dbw->addQuotes( $dbw->timestamp( $this->params['casTime'] ) ) .
  61. ' OR wl_notificationtimestamp IS NULL';
  62. $firstBatch = true;
  63. do {
  64. $idsToUpdate = $dbw->selectFieldValues(
  65. 'watchlist',
  66. 'wl_id',
  67. [
  68. 'wl_user' => $this->params['userId'],
  69. $timestampCond,
  70. $casTimeCond,
  71. ],
  72. __METHOD__,
  73. [ 'LIMIT' => $rowsPerQuery ]
  74. );
  75. if ( $idsToUpdate ) {
  76. $dbw->update(
  77. 'watchlist',
  78. [ 'wl_notificationtimestamp' => $timestamp ],
  79. [
  80. 'wl_id' => $idsToUpdate,
  81. // For paranoia, enforce the CAS time condition here too
  82. $casTimeCond
  83. ],
  84. __METHOD__
  85. );
  86. if ( !$firstBatch ) {
  87. $lbFactory->commitAndWaitForReplication( __METHOD__, $ticket );
  88. }
  89. $firstBatch = false;
  90. }
  91. } while ( $idsToUpdate );
  92. return true;
  93. }
  94. }