MediaWiki  master
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 
63 
70  public function __construct( Title $pageTitle, RevisionRecord $revision = null ) {
71  $this->pageTitle = $pageTitle;
72  $this->revision = $revision;
73  if ( $revision === null ) {
74  $this->timestamp = wfTimestampNow();
75  } else {
76  $this->timestamp = $revision->getTimestamp();
77  }
78  $this->newForCategorizationCallback = [ RecentChange::class, 'newForCategorization' ];
79  }
80 
90  public function overrideNewForCategorizationCallback( callable $callback ) {
91  if ( !defined( 'MW_PHPUNIT_TEST' ) ) {
92  throw new MWException( 'Cannot override newForCategorization callback in operation.' );
93  }
94  $this->newForCategorizationCallback = $callback;
95  }
96 
100  public function checkTemplateLinks() {
101  $this->numTemplateLinks = $this->pageTitle->getBacklinkCache()->getNumLinks( 'templatelinks' );
102  }
103 
109  public function triggerCategoryAddedNotification( Title $categoryTitle ) {
110  $this->createRecentChangesEntry( $categoryTitle, self::CATEGORY_ADDITION );
111  }
112 
118  public function triggerCategoryRemovedNotification( Title $categoryTitle ) {
119  $this->createRecentChangesEntry( $categoryTitle, self::CATEGORY_REMOVAL );
120  }
121 
128  private function createRecentChangesEntry( Title $categoryTitle, $type ) {
129  $this->notifyCategorization(
130  $this->timestamp,
131  $categoryTitle,
132  $this->getUser(),
133  $this->getChangeMessageText(
134  $type,
135  $this->pageTitle->getPrefixedText(),
136  $this->numTemplateLinks
137  ),
138  $this->pageTitle,
139  $this->getPreviousRevisionTimestamp(),
140  $this->revision,
141  $type === self::CATEGORY_ADDITION
142  );
143  }
144 
157  private function notifyCategorization(
158  $timestamp,
159  Title $categoryTitle,
160  ?UserIdentity $user,
161  $comment,
163  $lastTimestamp,
164  $revision,
165  $added
166  ) {
167  $deleted = $revision ? $revision->getVisibility() & RevisionRecord::SUPPRESSED_USER : 0;
168  $newRevId = $revision ? $revision->getId() : 0;
169 
175  $bot = 1;
176  $lastRevId = 0;
177  $ip = '';
178 
179  # If no revision is given, the change was probably triggered by parser functions
180  if ( $revision !== null ) {
181  $revisionStore = MediaWikiServices::getInstance()->getRevisionStore();
182 
183  $correspondingRc = $revisionStore->getRecentChange( $this->revision );
184  if ( $correspondingRc === null ) {
185  $correspondingRc = $revisionStore->getRecentChange(
186  $this->revision,
187  RevisionStore::READ_LATEST
188  );
189  }
190  if ( $correspondingRc !== null ) {
191  $bot = $correspondingRc->getAttribute( 'rc_bot' ) ?: 0;
192  $ip = $correspondingRc->getAttribute( 'rc_ip' ) ?: '';
193  $lastRevId = $correspondingRc->getAttribute( 'rc_last_oldid' ) ?: 0;
194  }
195  }
196 
199  $timestamp,
200  $categoryTitle,
201  $user,
202  $comment,
203  $pageTitle,
204  $lastRevId,
205  $newRevId,
206  $lastTimestamp,
207  $bot,
208  $ip,
209  $deleted,
210  $added
211  );
212  $rc->save();
213  }
214 
226  private function getUser(): ?UserIdentity {
227  if ( $this->revision ) {
228  $user = $this->revision->getUser( RevisionRecord::RAW );
229  if ( $user ) {
230  return $user;
231  }
232  }
233 
234  $username = wfMessage( 'autochange-username' )->inContentLanguage()->text();
235 
236  // TODO: use User::newSystemUser
237  $user = User::newFromName( $username );
238  # User::newFromName() can return false on a badly configured wiki.
239  if ( $user && !$user->isRegistered() ) {
240  $user->addToDatabase();
241  }
242 
243  return $user ?: null;
244  }
245 
262  private function getChangeMessageText( $type, $prefixedText, $numTemplateLinks ) {
263  $array = [
264  self::CATEGORY_ADDITION => 'recentchanges-page-added-to-category',
265  self::CATEGORY_REMOVAL => 'recentchanges-page-removed-from-category',
266  ];
267 
268  $msgKey = $array[$type];
269 
270  if ( intval( $numTemplateLinks ) > 0 ) {
271  $msgKey .= '-bundled';
272  }
273 
274  return wfMessage( $msgKey, $prefixedText )->inContentLanguage()->text();
275  }
276 
283  private function getPreviousRevisionTimestamp() {
284  $rl = MediaWikiServices::getInstance()->getRevisionLookup();
285  $latestRev = $rl->getRevisionByTitle( $this->pageTitle );
286  if ( $latestRev ) {
287  $previousRev = $rl->getPreviousRevision( $latestRev );
288  if ( $previousRev ) {
289  return $previousRev->getTimestamp();
290  }
291  }
292  return null;
293  }
294 
295 }
MediaWiki\Revision\RevisionRecord
Page revision base class.
Definition: RevisionRecord.php:47
CategoryMembershipChange\$newForCategorizationCallback
callable null $newForCategorizationCallback
Definition: CategoryMembershipChange.php:62
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:186
CategoryMembershipChange\CATEGORY_ADDITION
const CATEGORY_ADDITION
Definition: CategoryMembershipChange.php:34
MediaWiki\Revision\RevisionStore
Service for looking up page revisions.
Definition: RevisionStore.php:88
CategoryMembershipChange\overrideNewForCategorizationCallback
overrideNewForCategorizationCallback(callable $callback)
Overrides the default new for categorization callback This is intended for use while testing and will...
Definition: CategoryMembershipChange.php:90
CategoryMembershipChange\$pageTitle
Title $pageTitle
Title instance of the categorized page.
Definition: CategoryMembershipChange.php:45
User\newFromName
static newFromName( $name, $validate='valid')
Definition: User.php:602
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1182
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:39
CategoryMembershipChange\notifyCategorization
notifyCategorization( $timestamp, Title $categoryTitle, ?UserIdentity $user, $comment, Title $pageTitle, $lastTimestamp, $revision, $added)
Definition: CategoryMembershipChange.php:157
CategoryMembershipChange\__construct
__construct(Title $pageTitle, RevisionRecord $revision=null)
Definition: CategoryMembershipChange.php:70
MWException
MediaWiki exception.
Definition: MWException.php:29
CategoryMembershipChange\getChangeMessageText
getChangeMessageText( $type, $prefixedText, $numTemplateLinks)
Returns the change message according to the type of category membership change.
Definition: CategoryMembershipChange.php:262
CategoryMembershipChange\triggerCategoryRemovedNotification
triggerCategoryRemovedNotification(Title $categoryTitle)
Create a recentchanges entry for category removals.
Definition: CategoryMembershipChange.php:118
wfTimestampNow
wfTimestampNow()
Convenience function; returns MediaWiki timestamp for the present time.
Definition: GlobalFunctions.php:1721
CategoryMembershipChange\triggerCategoryAddedNotification
triggerCategoryAddedNotification(Title $categoryTitle)
Create a recentchanges entry for category additions.
Definition: CategoryMembershipChange.php:109
CategoryMembershipChange\$timestamp
string $timestamp
Current timestamp, set during CategoryMembershipChange::__construct()
Definition: CategoryMembershipChange.php:40
CategoryMembershipChange\getPreviousRevisionTimestamp
getPreviousRevisionTimestamp()
Returns the timestamp of the page's previous revision or null if the latest revision does not refer t...
Definition: CategoryMembershipChange.php:283
CategoryMembershipChange\getUser
getUser()
Get the user associated with this change.
Definition: CategoryMembershipChange.php:226
CategoryMembershipChange\createRecentChangesEntry
createRecentChangesEntry(Title $categoryTitle, $type)
Create a recentchanges entry using RecentChange::notifyCategorization()
Definition: CategoryMembershipChange.php:128
Title
Represents a title within MediaWiki.
Definition: Title.php:49
CategoryMembershipChange\CATEGORY_REMOVAL
const CATEGORY_REMOVAL
Definition: CategoryMembershipChange.php:35
MediaWiki\Revision\RevisionRecord\getId
getId( $wikiId=self::LOCAL)
Get revision ID.
Definition: RevisionRecord.php:279
MediaWiki\Revision\RevisionRecord\getTimestamp
getTimestamp()
MCR migration note: this replaced Revision::getTimestamp.
Definition: RevisionRecord.php:459
CategoryMembershipChange
Definition: CategoryMembershipChange.php:32
CategoryMembershipChange\$numTemplateLinks
int $numTemplateLinks
Number of pages this WikiPage is embedded by Set by CategoryMembershipChange::checkTemplateLinks()
Definition: CategoryMembershipChange.php:57
CategoryMembershipChange\$revision
RevisionRecord null $revision
Latest revision of the categorized page.
Definition: CategoryMembershipChange.php:50
CategoryMembershipChange\checkTemplateLinks
checkTemplateLinks()
Determines the number of template links for recursive link updates.
Definition: CategoryMembershipChange.php:100
MediaWiki\Revision\RevisionRecord\getVisibility
getVisibility()
Get the deletion bitfield of the revision.
Definition: RevisionRecord.php:448
$type
$type
Definition: testCompression.php:52