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 
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.
Definition: MWException.php:29
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:52
static newSystemUser( $name, $options=[])
Static factory method for creation of a "system" user from username.
Definition: User.php:795
Interface for objects representing user identity.