MediaWiki REL1_34
UserEditCountUpdate.php
Go to the documentation of this file.
1<?php
23use Wikimedia\Assert\Assert;
25
31 private $infoByUser;
32
37 public function __construct( User $user, $increment ) {
38 if ( !$user->getId() ) {
39 throw new RuntimeException( "Got user ID of zero" );
40 }
41 $this->infoByUser = [
42 $user->getId() => [ 'increment' => $increment, 'instances' => [ $user ] ]
43 ];
44 }
45
46 public function merge( MergeableUpdate $update ) {
48 Assert::parameterType( __CLASS__, $update, '$update' );
49 '@phan-var UserEditCountUpdate $update';
50
51 foreach ( $update->infoByUser as $userId => $info ) {
52 if ( !isset( $this->infoByUser[$userId] ) ) {
53 $this->infoByUser[$userId] = [ 'increment' => 0, 'instances' => [] ];
54 }
55 // Merge the increment amount
56 $this->infoByUser[$userId]['increment'] += $info['increment'];
57 // Merge the list of User instances to update in doUpdate()
58 foreach ( $info['instances'] as $user ) {
59 if ( !in_array( $user, $this->infoByUser[$userId]['instances'], true ) ) {
60 $this->infoByUser[$userId]['instances'][] = $user;
61 }
62 }
63 }
64 }
65
69 public function doUpdate() {
70 $lb = MediaWikiServices::getInstance()->getDBLoadBalancer();
71 $dbw = $lb->getConnectionRef( DB_MASTER );
72 $fname = __METHOD__;
73
74 ( new AutoCommitUpdate( $dbw, __METHOD__, function () use ( $lb, $dbw, $fname ) {
75 foreach ( $this->infoByUser as $userId => $info ) {
76 $dbw->update(
77 'user',
78 [ 'user_editcount=user_editcount+' . (int)$info['increment'] ],
79 [ 'user_id' => $userId, 'user_editcount IS NOT NULL' ],
80 $fname
81 );
83 $affectedInstances = $info['instances'];
84 // Lazy initialization check...
85 if ( $dbw->affectedRows() == 0 ) {
86 // The user_editcount is probably NULL (e.g. not initialized).
87 // Since this update runs after the new revisions were committed,
88 // wait for the replica DB to catch up so they will be counted.
89 $dbr = $lb->getConnectionRef( DB_REPLICA );
90 // If $dbr is actually the master DB, then clearing the snapshot
91 // is harmless and waitForMasterPos() will just no-op.
92 $dbr->flushSnapshot( $fname );
93 $lb->waitForMasterPos( $dbr );
94 $affectedInstances[0]->initEditCountInternal( $dbr );
95 }
96 $newCount = (int)$dbw->selectField(
97 'user',
98 'user_editcount',
99 [ 'user_id' => $userId ],
100 $fname
101 );
102
103 // Update the edit count in the instance caches. This is mostly useful
104 // for maintenance scripts, where deferred updates might run immediately
105 // and user instances might be reused for a long time.
106 foreach ( $affectedInstances as $affectedInstance ) {
107 $affectedInstance->setEditCountInternal( $newCount );
108 }
109 // Clear the edit count in user cache too
110 $affectedInstances[0]->invalidateCache();
111 }
112 } ) )->doUpdate();
113 }
114}
Deferrable Update for closure/callback updates that should use auto-commit mode.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Handles increment the edit count for a given set of users.
__construct(User $user, $increment)
array[] $infoByUser
Map of (user ID => ('increment': int, 'instances': User[]))
doUpdate()
Purges the list of URLs passed to the constructor.
merge(MergeableUpdate $update)
Merge this update with $update.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:51
getId()
Get the user's ID.
Definition User.php:2335
Interface that deferrable updates should implement.
Interface that deferrable updates can implement to signal that updates can be combined.
const DB_MASTER
Definition defines.php:26