5use InvalidArgumentException;
15use Wikimedia\Timestamp\ConvertibleTimestamp;
26 private const FIRST_EDIT = 1;
27 private const LATEST_EDIT = 2;
41 private $userEditCountCache = [];
53 $this->actorNormalization = $actorNormalization;
54 $this->dbProvider = $dbProvider;
55 $this->jobQueueGroup = $jobQueueGroup;
65 if ( !$user->isRegistered() ) {
69 $cacheKey = $this->getCacheKey( $user );
70 if ( isset( $this->userEditCountCache[ $cacheKey ] ) ) {
71 return $this->userEditCountCache[ $cacheKey ];
75 $userId = $user->
getId( $wikiId );
76 $count = $this->dbProvider->getReplicaDatabase( $wikiId )->newSelectQueryBuilder()
77 ->select(
'user_editcount' )
79 ->where( [
'user_id' => $userId ] )
80 ->caller( __METHOD__ )->fetchField();
82 if ( $count ===
null ) {
87 $this->userEditCountCache[ $cacheKey ] = $count;
99 throw new LogicException( __METHOD__ .
' only supports local users' );
102 $dbr = $this->dbProvider->getReplicaDatabase();
103 $count = (int)$dbr->newSelectQueryBuilder()
104 ->select(
'COUNT(*)' )
106 ->where( [
'rev_actor' => $this->actorNormalization->findActorId( $user, $dbr ) ] )
107 ->caller( __METHOD__ )
112 'userId' => $user->
getId(),
113 'editCount' => $count,
131 DeferredUpdates::addUpdate(
133 DeferredUpdates::POSTSEND
146 return $this->getUserEditTimestamp( $user, self::FIRST_EDIT, $flags );
158 return $this->getUserEditTimestamp( $user, self::LATEST_EDIT, $flags );
169 private function getUserEditTimestamp(
UserIdentity $user,
int $type,
int $flags = IDBAccessObject::READ_NORMAL ) {
173 if ( $flags & IDBAccessObject::READ_LATEST ) {
174 $db = $this->dbProvider->getPrimaryDatabase( $user->
getWikiId() );
176 $db = $this->dbProvider->getReplicaDatabase( $user->
getWikiId() );
179 $sortOrder = ( $type === self::FIRST_EDIT ) ? SelectQueryBuilder::SORT_ASC : SelectQueryBuilder::SORT_DESC;
180 $time = $db->newSelectQueryBuilder()
181 ->select(
'rev_timestamp' )
183 ->where( [
'rev_actor' => $this->actorNormalization->findActorId( $user, $db ) ] )
184 ->orderBy(
'rev_timestamp', $sortOrder )
185 ->caller( __METHOD__ )
192 return ConvertibleTimestamp::convert( TS_MW, $time );
204 $cacheKey = $this->getCacheKey( $user );
205 unset( $this->userEditCountCache[ $cacheKey ] );
216 throw new InvalidArgumentException( __METHOD__ .
' with an anonymous user' );
219 $cacheKey = $this->getCacheKey( $user );
220 $this->userEditCountCache[ $cacheKey ] = $editCount;
223 private function getCacheKey(
UserIdentity $user ): string {
224 if ( !$user->isRegistered() ) {
225 throw new InvalidArgumentException(
'Cannot prepare cache key for an anonymous user' );
229 $userId = $user->
getId( $wikiId );
230 $isRemoteWiki = ( $wikiId !== UserIdentity::LOCAL ) && !WikiMap::isCurrentWikiId( $wikiId );
231 if ( $isRemoteWiki ) {
232 return $wikiId .
':u' . $userId;
234 return 'u' . $userId;
if(!defined('MW_SETUP_CALLBACK'))
Job that initializes an user's edit count.