MediaWiki 1.40.4
CategoryMembershipChange.php
Go to the documentation of this file.
1<?php
2
8
34
35 private const CATEGORY_ADDITION = 1;
36 private const CATEGORY_REMOVAL = -1;
37
41 private $timestamp;
42
46 private $pageTitle;
47
51 private $revision;
52
58 private $numTemplateLinks = 0;
59
63 private $newForCategorizationCallback = null;
64
66 private $backlinkCache;
67
75 public function __construct(
76 Title $pageTitle, BacklinkCache $backlinkCache, RevisionRecord $revision = null
77 ) {
78 $this->pageTitle = $pageTitle;
79 $this->revision = $revision;
80 if ( $revision === null ) {
81 $this->timestamp = wfTimestampNow();
82 } else {
83 $this->timestamp = $revision->getTimestamp();
84 }
85 $this->newForCategorizationCallback = [ RecentChange::class, 'newForCategorization' ];
86 $this->backlinkCache = $backlinkCache;
87 }
88
98 public function overrideNewForCategorizationCallback( callable $callback ) {
99 if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
100 throw new MWException( 'Cannot override newForCategorization callback in operation.' );
101 }
102 $this->newForCategorizationCallback = $callback;
103 }
104
108 public function checkTemplateLinks() {
109 $this->numTemplateLinks = $this->backlinkCache->getNumLinks( 'templatelinks' );
110 }
111
117 public function triggerCategoryAddedNotification( Title $categoryTitle ) {
118 $this->createRecentChangesEntry( $categoryTitle, self::CATEGORY_ADDITION );
119 }
120
126 public function triggerCategoryRemovedNotification( Title $categoryTitle ) {
127 $this->createRecentChangesEntry( $categoryTitle, self::CATEGORY_REMOVAL );
128 }
129
136 private function createRecentChangesEntry( Title $categoryTitle, $type ) {
137 $this->notifyCategorization(
138 $this->timestamp,
139 $categoryTitle,
140 $this->getUser(),
141 $this->getChangeMessageText(
142 $type,
143 $this->pageTitle->getPrefixedText(),
144 $this->numTemplateLinks
145 ),
146 $this->pageTitle,
147 $this->getPreviousRevisionTimestamp(),
148 $this->revision,
149 $type === self::CATEGORY_ADDITION
150 );
151 }
152
165 private function notifyCategorization(
166 $timestamp,
167 Title $categoryTitle,
168 ?UserIdentity $user,
169 $comment,
170 Title $pageTitle,
171 $lastTimestamp,
172 $revision,
173 $added
174 ) {
175 $deleted = $revision ? $revision->getVisibility() & RevisionRecord::SUPPRESSED_USER : 0;
176 $newRevId = $revision ? $revision->getId() : 0;
177
183 $bot = 1;
184 $lastRevId = 0;
185 $ip = '';
186
187 # If no revision is given, the change was probably triggered by parser functions
188 if ( $revision !== null ) {
189 $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
190
191 $correspondingRc = $revisionStore->getRecentChange( $this->revision ) ??
192 $revisionStore->getRecentChange( $this->revision, RevisionStore::READ_LATEST );
193 if ( $correspondingRc !== null ) {
194 $bot = $correspondingRc->getAttribute( 'rc_bot' ) ?: 0;
195 $ip = $correspondingRc->getAttribute( 'rc_ip' ) ?: '';
196 $lastRevId = $correspondingRc->getAttribute( 'rc_last_oldid' ) ?: 0;
197 }
198 }
199
201 $rc = ( $this->newForCategorizationCallback )(
202 $timestamp,
203 $categoryTitle,
204 $user,
205 $comment,
206 $pageTitle,
207 $lastRevId,
208 $newRevId,
209 $lastTimestamp,
210 $bot,
211 $ip,
212 $deleted,
213 $added
214 );
215 $rc->save();
216 }
217
229 private function getUser(): ?UserIdentity {
230 if ( $this->revision ) {
231 $user = $this->revision->getUser( RevisionRecord::RAW );
232 if ( $user ) {
233 return $user;
234 }
235 }
236
237 $username = wfMessage( 'autochange-username' )->inContentLanguage()->text();
238
239 $user = User::newSystemUser( $username );
240 if ( $user && !$user->isRegistered() ) {
241 $user->addToDatabase();
242 }
243
244 return $user ?: null;
245 }
246
263 private function getChangeMessageText( $type, $prefixedText, $numTemplateLinks ) {
264 $array = [
265 self::CATEGORY_ADDITION => 'recentchanges-page-added-to-category',
266 self::CATEGORY_REMOVAL => 'recentchanges-page-removed-from-category',
267 ];
268
269 $msgKey = $array[$type];
270
271 if ( intval( $numTemplateLinks ) > 0 ) {
272 $msgKey .= '-bundled';
273 }
274
275 return wfMessage( $msgKey, $prefixedText )->inContentLanguage()->text();
276 }
277
284 private function getPreviousRevisionTimestamp() {
285 $rl = MediaWikiServices::getInstance()->getRevisionLookup();
286 $latestRev = $rl->getRevisionByTitle( $this->pageTitle );
287 if ( $latestRev ) {
288 $previousRev = $rl->getPreviousRevision( $latestRev );
289 if ( $previousRev ) {
290 return $previousRev->getTimestamp();
291 }
292 }
293 return null;
294 }
295
296}
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
Definition WebStart.php:88
Class for fetching backlink lists, approximate backlink counts and partitions.
triggerCategoryRemovedNotification(Title $categoryTitle)
Create a recentchanges entry for category removals.
triggerCategoryAddedNotification(Title $categoryTitle)
Create a recentchanges entry for category additions.
overrideNewForCategorizationCallback(callable $callback)
Overrides the default new for categorization callback This is intended for use while testing and will...
__construct(Title $pageTitle, BacklinkCache $backlinkCache, RevisionRecord $revision=null)
checkTemplateLinks()
Determines the number of template links for recursive link updates.
MediaWiki exception.
Service locator for MediaWiki core services.
Page revision base class.
getVisibility()
Get the deletion bitfield of the revision.
getTimestamp()
MCR migration note: this replaced Revision::getTimestamp.
getId( $wikiId=self::LOCAL)
Get revision ID.
Service for looking up page revisions.
Represents a title within MediaWiki.
Definition Title.php:82
static newSystemUser( $name, $options=[])
Static factory method for creation of a "system" user from username.
Definition User.php:793
Interface for objects representing user identity.