Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
BackfillUnreadWikis
0.00% covered (danger)
0.00%
0 / 48
0.00% covered (danger)
0.00%
0 / 2
156
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 43
0.00% covered (danger)
0.00%
0 / 1
132
1<?php
2
3use MediaWiki\Extension\Notifications\AttributeManager;
4use MediaWiki\Extension\Notifications\DbFactory;
5use MediaWiki\Extension\Notifications\NotifUser;
6use MediaWiki\Extension\Notifications\UnreadWikis;
7use MediaWiki\User\CentralId\CentralIdLookup;
8use MediaWiki\User\User;
9use MediaWiki\WikiMap\WikiMap;
10
11$IP = getenv( 'MW_INSTALL_PATH' );
12if ( $IP === false ) {
13    $IP = __DIR__ . '/../../..';
14}
15require_once "$IP/maintenance/Maintenance.php";
16
17class BackfillUnreadWikis extends Maintenance {
18    public function __construct() {
19        parent::__construct();
20
21        $this->addDescription( "Backfill echo_unread_wikis table" );
22        $this->addOption( 'rebuild', 'Only recompute already-existing rows' );
23        $this->setBatchSize( 300 );
24        $this->requireExtension( 'Echo' );
25    }
26
27    public function execute() {
28        $dbFactory = DbFactory::newFromDefault();
29        $lookup = $this->getServiceContainer()->getCentralIdLookup();
30
31        $rebuild = $this->hasOption( 'rebuild' );
32        if ( $rebuild ) {
33            $iterator = new BatchRowIterator(
34                $dbFactory->getSharedDb( DB_REPLICA ),
35                'echo_unread_wikis',
36                'euw_user',
37                $this->getBatchSize()
38            );
39            $iterator->addConditions( [ 'euw_wiki' => WikiMap::getCurrentWikiId() ] );
40        } else {
41            $userQuery = User::getQueryInfo();
42            $iterator = new BatchRowIterator(
43                $this->getReplicaDB(), $userQuery['tables'], 'user_id', $this->getBatchSize()
44            );
45            $iterator->setFetchColumns( $userQuery['fields'] );
46            $iterator->addJoinConditions( $userQuery['joins'] );
47        }
48
49        $iterator->setCaller( __METHOD__ );
50
51        $processed = 0;
52        foreach ( $iterator as $batch ) {
53            foreach ( $batch as $row ) {
54                if ( $rebuild ) {
55                    $user = $lookup->localUserFromCentralId(
56                        $row->euw_user,
57                        CentralIdLookup::AUDIENCE_RAW
58                    );
59                    if ( !$user ) {
60                        continue;
61                    }
62                } else {
63                    $user = User::newFromRow( $row );
64                }
65
66                $notifUser = NotifUser::newFromUser( $user );
67                $uw = UnreadWikis::newFromUser( $user );
68                if ( $uw ) {
69                    $alertCount = $notifUser->getNotificationCount( AttributeManager::ALERT, false );
70                    $alertUnread = $notifUser->getLastUnreadNotificationTime( AttributeManager::ALERT, false );
71
72                    $msgCount = $notifUser->getNotificationCount( AttributeManager::MESSAGE, false );
73                    $msgUnread = $notifUser->getLastUnreadNotificationTime( AttributeManager::MESSAGE, false );
74
75                    if ( ( $alertCount !== 0 && $alertUnread === false ) ||
76                        ( $msgCount !== 0 && $msgUnread === false )
77                    ) {
78                        // If there are alerts, there should be an alert timestamp (same for messages).
79
80                        // Otherwise, there is a race condition between the two values, indicating there's already
81                        // just been an updateCount call, so we can skip this user.
82                        continue;
83                    }
84
85                    $uw->updateCount( WikiMap::getCurrentWikiId(), $alertCount, $alertUnread, $msgCount, $msgUnread );
86                }
87            }
88
89            $processed += count( $batch );
90            $this->output( "Updated $processed users.\n" );
91            $this->waitForReplication();
92        }
93    }
94}
95
96$maintClass = BackfillUnreadWikis::class;
97require_once RUN_MAINTENANCE_IF_MAIN;