MediaWiki REL1_39
CategoryMembershipChange.php
Go to the documentation of this file.
1<?php
2
7
33
34 private const CATEGORY_ADDITION = 1;
35 private const CATEGORY_REMOVAL = -1;
36
40 private $timestamp;
41
45 private $pageTitle;
46
50 private $revision;
51
57 private $numTemplateLinks = 0;
58
62 private $newForCategorizationCallback = null;
63
65 private $backlinkCache;
66
74 public function __construct(
75 Title $pageTitle, BacklinkCache $backlinkCache, RevisionRecord $revision = null
76 ) {
77 $this->pageTitle = $pageTitle;
78 $this->revision = $revision;
79 if ( $revision === null ) {
80 $this->timestamp = wfTimestampNow();
81 } else {
82 $this->timestamp = $revision->getTimestamp();
83 }
84 $this->newForCategorizationCallback = [ RecentChange::class, 'newForCategorization' ];
85 $this->backlinkCache = $backlinkCache;
86 }
87
97 public function overrideNewForCategorizationCallback( callable $callback ) {
98 if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
99 throw new MWException( 'Cannot override newForCategorization callback in operation.' );
100 }
101 $this->newForCategorizationCallback = $callback;
102 }
103
107 public function checkTemplateLinks() {
108 $this->numTemplateLinks = $this->backlinkCache->getNumLinks( 'templatelinks' );
109 }
110
116 public function triggerCategoryAddedNotification( Title $categoryTitle ) {
117 $this->createRecentChangesEntry( $categoryTitle, self::CATEGORY_ADDITION );
118 }
119
125 public function triggerCategoryRemovedNotification( Title $categoryTitle ) {
126 $this->createRecentChangesEntry( $categoryTitle, self::CATEGORY_REMOVAL );
127 }
128
135 private function createRecentChangesEntry( Title $categoryTitle, $type ) {
136 $this->notifyCategorization(
137 $this->timestamp,
138 $categoryTitle,
139 $this->getUser(),
140 $this->getChangeMessageText(
141 $type,
142 $this->pageTitle->getPrefixedText(),
143 $this->numTemplateLinks
144 ),
145 $this->pageTitle,
146 $this->getPreviousRevisionTimestamp(),
147 $this->revision,
148 $type === self::CATEGORY_ADDITION
149 );
150 }
151
164 private function notifyCategorization(
165 $timestamp,
166 Title $categoryTitle,
167 ?UserIdentity $user,
168 $comment,
169 Title $pageTitle,
170 $lastTimestamp,
171 $revision,
172 $added
173 ) {
174 $deleted = $revision ? $revision->getVisibility() & RevisionRecord::SUPPRESSED_USER : 0;
175 $newRevId = $revision ? $revision->getId() : 0;
176
182 $bot = 1;
183 $lastRevId = 0;
184 $ip = '';
185
186 # If no revision is given, the change was probably triggered by parser functions
187 if ( $revision !== null ) {
188 $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
189
190 $correspondingRc = $revisionStore->getRecentChange( $this->revision );
191 if ( $correspondingRc === null ) {
192 $correspondingRc = $revisionStore->getRecentChange(
193 $this->revision,
194 RevisionStore::READ_LATEST
195 );
196 }
197 if ( $correspondingRc !== null ) {
198 $bot = $correspondingRc->getAttribute( 'rc_bot' ) ?: 0;
199 $ip = $correspondingRc->getAttribute( 'rc_ip' ) ?: '';
200 $lastRevId = $correspondingRc->getAttribute( 'rc_last_oldid' ) ?: 0;
201 }
202 }
203
205 $rc = ( $this->newForCategorizationCallback )(
206 $timestamp,
207 $categoryTitle,
208 $user,
209 $comment,
210 $pageTitle,
211 $lastRevId,
212 $newRevId,
213 $lastTimestamp,
214 $bot,
215 $ip,
216 $deleted,
217 $added
218 );
219 $rc->save();
220 }
221
233 private function getUser(): ?UserIdentity {
234 if ( $this->revision ) {
235 $user = $this->revision->getUser( RevisionRecord::RAW );
236 if ( $user ) {
237 return $user;
238 }
239 }
240
241 $username = wfMessage( 'autochange-username' )->inContentLanguage()->text();
242
243 $user = User::newSystemUser( $username );
244 if ( $user && !$user->isRegistered() ) {
245 $user->addToDatabase();
246 }
247
248 return $user ?: null;
249 }
250
267 private function getChangeMessageText( $type, $prefixedText, $numTemplateLinks ) {
268 $array = [
269 self::CATEGORY_ADDITION => 'recentchanges-page-added-to-category',
270 self::CATEGORY_REMOVAL => 'recentchanges-page-removed-from-category',
271 ];
272
273 $msgKey = $array[$type];
274
275 if ( intval( $numTemplateLinks ) > 0 ) {
276 $msgKey .= '-bundled';
277 }
278
279 return wfMessage( $msgKey, $prefixedText )->inContentLanguage()->text();
280 }
281
288 private function getPreviousRevisionTimestamp() {
289 $rl = MediaWikiServices::getInstance()->getRevisionLookup();
290 $latestRev = $rl->getRevisionByTitle( $this->pageTitle );
291 if ( $latestRev ) {
292 $previousRev = $rl->getPreviousRevision( $latestRev );
293 if ( $previousRev ) {
294 return $previousRev->getTimestamp();
295 }
296 }
297 return null;
298 }
299
300}
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:82
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:49
static newSystemUser( $name, $options=[])
Static factory method for creation of a "system" user from username.
Definition User.php:806
Interface for objects representing user identity.