MediaWiki  master
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'))
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.
Definition: MWException.php:32
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.