34use Wikimedia\Assert\Assert;
35use Wikimedia\AtEase\AtEase;
84 use DeprecationHelper;
101 public const SEND_NONE =
true;
106 public const SEND_FEED =
false;
115 private $mPage =
null;
120 private $mPerformer =
null;
143 private $editResult =
null;
145 private const CHANGE_TYPES = [
174 if ( is_array(
$type ) ) {
177 $retval[] = self::parseToRCType(
$t );
183 if ( !array_key_exists(
$type, self::CHANGE_TYPES ) ) {
186 return self::CHANGE_TYPES[
$type];
196 return array_search( $rcType, self::CHANGE_TYPES,
true ) ?:
"$rcType";
207 return array_keys( self::CHANGE_TYPES );
217 return self::newFromConds( [
'rc_id' => $rcid ], __METHOD__ );
235 $rcQuery = self::getQueryInfo();
236 $row = $db->selectRow(
237 $rcQuery[
'tables'], $rcQuery[
'fields'], $conds, $fname, [], $rcQuery[
'joins']
239 if ( $row !==
false ) {
240 return self::newFromRow( $row );
262 $commentQuery = CommentStore::getStore()->getJoin(
'rc_comment' );
264 $commentQuery[
'joins'][
'comment_rc_comment'][0] =
'STRAIGHT_JOIN';
268 'recentchanges_actor' =>
'actor'
269 ] + $commentQuery[
'tables'],
293 'rc_user' =>
'recentchanges_actor.actor_user',
294 'rc_user_text' =>
'recentchanges_actor.actor_name',
295 ] + $commentQuery[
'fields'],
297 'recentchanges_actor' => [
'STRAIGHT_JOIN',
'actor_id=rc_actor' ]
298 ] + $commentQuery[
'joins'],
307 return Title::castFromPageReference( $this->mPage );
321 $this->mAttribs = $attribs;
328 $this->mExtra = $extra;
336 $this->mPage = Title::castFromPageReference( $this->
getPage() );
337 return $this->mPage ?: Title::makeTitle(
NS_SPECIAL,
'BadTitle' );
345 if ( !$this->mPage ) {
350 if ( ( $this->mAttribs[
'rc_title'] ??
'' ) ===
'' ) {
359 (
int)$this->mAttribs[
'rc_namespace'],
360 $this->mAttribs[
'rc_title'],
376 if ( !$this->mPerformer instanceof
User ) {
380 return $this->mPerformer;
391 if ( !$this->mPerformer ) {
392 $this->mPerformer = $this->getUserIdentityFromAnyId(
393 $this->mAttribs[
'rc_user'] ??
null,
394 $this->mAttribs[
'rc_user_text'] ??
null,
395 $this->mAttribs[
'rc_actor'] ??
null
399 return $this->mPerformer;
411 public function save( $send = self::SEND_FEED ) {
412 $mainConfig = MediaWikiServices::getInstance()->getMainConfig();
413 $putIPinRC = $mainConfig->get( MainConfigNames::PutIPinRC );
415 if ( !is_array( $this->mExtra ) ) {
420 $this->mAttribs[
'rc_ip'] =
'';
423 # Strict mode fixups (not-NULL fields)
424 foreach ( [
'minor',
'bot',
'new',
'patrolled',
'deleted' ] as $field ) {
425 $this->mAttribs[
"rc_$field"] = (int)$this->mAttribs[
"rc_$field"];
427 # ...more fixups (NULL fields)
428 foreach ( [
'old_len',
'new_len' ] as $field ) {
429 $this->mAttribs[
"rc_$field"] = isset( $this->mAttribs[
"rc_$field"] )
430 ? (int)$this->mAttribs[
"rc_$field"]
434 $row = $this->mAttribs;
436 # Trim spaces on user supplied text
437 $row[
'rc_comment'] = trim( $row[
'rc_comment'] );
439 # Fixup database timestamps
440 $row[
'rc_timestamp'] = $dbw->timestamp( $row[
'rc_timestamp'] );
442 # # If we are using foreign keys, an entry of 0 for the page_id will fail, so use NULL
443 if ( $row[
'rc_cur_id'] == 0 ) {
444 unset( $row[
'rc_cur_id'] );
447 # Convert mAttribs['rc_comment'] for CommentStore
448 $comment = $row[
'rc_comment'];
449 unset( $row[
'rc_comment'], $row[
'rc_comment_text'], $row[
'rc_comment_data'] );
450 $row += CommentStore::getStore()->insert( $dbw,
'rc_comment', $comment );
452 # Normalize UserIdentity to actor ID
453 $user = $this->getPerformerIdentity();
454 $actorStore = MediaWikiServices::getInstance()->getActorStore();
455 $row[
'rc_actor'] = $actorStore->acquireActorId( $user, $dbw );
456 unset( $row[
'rc_user'], $row[
'rc_user_text'] );
458 # Don't reuse an existing rc_id for the new row, if one happens to be
459 # set for some reason.
460 unset( $row[
'rc_id'] );
463 $dbw->insert(
'recentchanges', $row, __METHOD__ );
466 $this->mAttribs[
'rc_id'] = $dbw->insertId();
469 Hooks::runner()->onRecentChange_save( $this );
472 if ( $this->editResult !==
null && count( $this->editResult->getRevertTags() ) ) {
474 $this->editResult->getRevertTags(),
475 $this->mAttribs[
'rc_id'],
476 $this->mAttribs[
'rc_this_oldid'],
477 $this->mAttribs[
'rc_logid'],
478 FormatJson::encode( $this->editResult ),
483 if ( count( $this->tags ) ) {
488 $this->mAttribs[
'rc_id'],
489 $this->mAttribs[
'rc_this_oldid'],
490 $this->mAttribs[
'rc_logid'],
496 if ( $send === self::SEND_FEED ) {
498 $this->notifyRCFeeds();
501 # E-mail notifications
502 if ( $mainConfig->get( MainConfigNames::EnotifUserTalk ) ||
503 $mainConfig->get( MainConfigNames::EnotifWatchlist ) ||
504 $mainConfig->get( MainConfigNames::ShowUpdatedMarker )
506 $userFactory = MediaWikiServices::getInstance()->getUserFactory();
507 $editor = $userFactory->newFromUserIdentity( $this->getPerformerIdentity() );
508 $page = $this->getPage();
509 $title = Title::castFromPageReference( $page );
514 Hooks::runner()->onAbortEmailNotification( $editor,
$title, $this ) &&
519 $dbw->onTransactionCommitOrIdle(
520 function () use ( $editor,
$title ) {
522 $enotif->notifyOnPageChange(
525 $this->mAttribs[
'rc_timestamp'],
526 $this->mAttribs[
'rc_comment'],
527 $this->mAttribs[
'rc_minor'],
528 $this->mAttribs[
'rc_last_oldid'],
529 $this->mExtra[
'pageStatus']
539 if ( mt_rand( 0, 9 ) == 0 ) {
540 $jobs[] = RecentChangesUpdateJob::newPurgeJob();
543 if ( $this->mAttribs[
'rc_user'] > 0 ) {
544 $jobs[] = RecentChangesUpdateJob::newCacheUpdateJob();
546 MediaWikiServices::getInstance()->getJobQueueGroup()->lazyPush( $jobs );
556 if ( $this->mAttribs[
'rc_deleted'] != 0 ) {
561 MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::RCFeeds );
562 if ( $feeds ===
null ) {
566 $performer = $this->getPerformerIdentity();
568 foreach ( $feeds as $params ) {
570 'omit_bots' =>
false,
571 'omit_anon' =>
false,
572 'omit_user' =>
false,
573 'omit_minor' =>
false,
574 'omit_patrolled' =>
false,
578 ( $params[
'omit_bots'] && $this->mAttribs[
'rc_bot'] ) ||
579 ( $params[
'omit_anon'] && !$performer->isRegistered() ) ||
580 ( $params[
'omit_user'] && $performer->isRegistered() ) ||
581 ( $params[
'omit_minor'] && $this->mAttribs[
'rc_minor'] ) ||
582 ( $params[
'omit_patrolled'] && $this->mAttribs[
'rc_patrolled'] ) ||
588 $actionComment = $this->mExtra[
'actionCommentIRC'] ??
null;
591 $feed->notify( $this, $actionComment );
604 public static function getEngine( $uri, $params = [] ) {
607 MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::RCEngines );
608 $scheme = parse_url( $uri, PHP_URL_SCHEME );
610 throw new MWException(
"Invalid RCFeed uri: '$uri'" );
612 if ( !isset( $rcEngines[$scheme] ) ) {
613 throw new MWException(
"Unknown RCFeed engine: '$scheme'" );
615 if ( defined(
'MW_PHPUNIT_TEST' ) && is_object( $rcEngines[$scheme] ) ) {
616 return $rcEngines[$scheme];
618 return new $rcEngines[$scheme]( $params );
633 $mainConfig = MediaWikiServices::getInstance()->getMainConfig();
634 $useRCPatrol = $mainConfig->get( MainConfigNames::UseRCPatrol );
635 $useNPPatrol = $mainConfig->get( MainConfigNames::UseNPPatrol );
636 $useFilePatrol = $mainConfig->get( MainConfigNames::UseFilePatrol );
638 if ( $tags ===
null ) {
640 } elseif ( is_string( $tags ) ) {
644 $status = PermissionStatus::newEmpty();
647 if ( !$useRCPatrol && ( !$useNPPatrol || $this->getAttribute(
'rc_type' ) !=
RC_NEW ) &&
648 ( !$useFilePatrol || !( $this->getAttribute(
'rc_type' ) ==
RC_LOG &&
649 $this->getAttribute(
'rc_log_type' ) ==
'upload' ) ) ) {
650 $status->fatal(
'rcpatroldisabled' );
654 $user = MediaWikiServices::getInstance()->getUserFactory()->newFromAuthority( $performer );
655 if ( !Hooks::runner()->onMarkPatrolled(
656 $this->getAttribute(
'rc_id' ), $user,
false, $auto, $tags )
658 $status->fatal(
'hookaborted' );
661 if ( $performer->
getUser()->getName() === $this->getAttribute(
'rc_user_text' ) &&
664 $status->fatal(
'markedaspatrollederror-noautopatrol' );
666 if ( !$status->isGood() ) {
667 return $status->toLegacyErrorArray();
670 if ( $this->getAttribute(
'rc_patrolled' ) ) {
674 $this->reallyMarkPatrolled();
678 Hooks::runner()->onMarkPatrolledComplete(
679 $this->getAttribute(
'rc_id' ), $user,
false, $auto );
693 'rc_patrolled' => self::PRC_PATROLLED
696 'rc_id' => $this->getAttribute(
'rc_id' )
702 $this->
getTitle()->invalidateCache();
705 $revisionId = $this->getAttribute(
'rc_this_oldid' );
707 $revertedTagUpdateManager =
708 MediaWikiServices::getInstance()->getRevertedTagUpdateManager();
709 $revertedTagUpdateManager->approveRevertedTagForRevision( $revisionId );
712 return $dbw->affectedRows();
740 $timestamp, $page, $minor, $user, $comment, $oldId, $lastTimestamp,
741 $bot, $ip =
'', $oldSize = 0, $newSize = 0, $newId = 0, $patrol = 0,
744 Assert::parameter( $page->exists(),
'$page',
'must represent an existing page' );
748 $rc->mPerformer = $user;
750 'rc_timestamp' => $timestamp,
751 'rc_namespace' => $page->getNamespace(),
752 'rc_title' => $page->getDBkey(),
754 'rc_source' => self::SRC_EDIT,
755 'rc_minor' => $minor ? 1 : 0,
756 'rc_cur_id' => $page->getId(),
757 'rc_user' => $user->getId(),
758 'rc_user_text' => $user->getName(),
759 'rc_comment' => &$comment,
760 'rc_comment_text' => &$comment,
761 'rc_comment_data' =>
null,
762 'rc_this_oldid' => (int)$newId,
763 'rc_last_oldid' => $oldId,
764 'rc_bot' => $bot ? 1 : 0,
765 'rc_ip' => self::checkIPAddress( $ip ),
766 'rc_patrolled' => intval( $patrol ),
767 'rc_new' => 0, # obsolete
768 'rc_old_len' => $oldSize,
769 'rc_new_len' => $newSize,
772 'rc_log_type' =>
null,
773 'rc_log_action' =>
'',
778 $formatter = MediaWikiServices::getInstance()->getTitleFormatter();
781 'prefixedDBkey' => $formatter->getPrefixedDBkey( $page ),
782 'lastTimestamp' => $lastTimestamp,
783 'oldSize' => $oldSize,
784 'newSize' => $newSize,
785 'pageStatus' =>
'changed'
788 DeferredUpdates::addCallableUpdate(
789 static function () use ( $rc, $tags, $editResult ) {
790 $rc->addTags( $tags );
791 $rc->setEditResult( $editResult );
794 DeferredUpdates::POSTSEND,
822 $page, $minor, $user, $comment, $bot,
823 $ip =
'', $size = 0, $newId = 0, $patrol = 0, $tags = []
825 Assert::parameter( $page->exists(),
'$page',
'must represent an existing page' );
829 $rc->mPerformer = $user;
831 'rc_timestamp' => $timestamp,
832 'rc_namespace' => $page->getNamespace(),
833 'rc_title' => $page->getDBkey(),
835 'rc_source' => self::SRC_NEW,
836 'rc_minor' => $minor ? 1 : 0,
837 'rc_cur_id' => $page->getId(),
838 'rc_user' => $user->getId(),
839 'rc_user_text' => $user->getName(),
840 'rc_comment' => &$comment,
841 'rc_comment_text' => &$comment,
842 'rc_comment_data' =>
null,
843 'rc_this_oldid' => (int)$newId,
844 'rc_last_oldid' => 0,
845 'rc_bot' => $bot ? 1 : 0,
846 'rc_ip' => self::checkIPAddress( $ip ),
847 'rc_patrolled' => intval( $patrol ),
848 'rc_new' => 1, # obsolete
850 'rc_new_len' => $size,
853 'rc_log_type' =>
null,
854 'rc_log_action' =>
'',
859 $formatter = MediaWikiServices::getInstance()->getTitleFormatter();
862 'prefixedDBkey' => $formatter->getPrefixedDBkey( $page ),
863 'lastTimestamp' => 0,
866 'pageStatus' =>
'created'
869 DeferredUpdates::addCallableUpdate(
870 static function () use ( $rc, $tags ) {
871 $rc->addTags( $tags );
874 DeferredUpdates::POSTSEND,
898 $logPage, $user, $actionComment, $ip,
$type,
899 $action, $target, $logComment, $params, $newId = 0, $actionCommentIRC =
''
901 $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()
902 ->get( MainConfigNames::LogRestrictions );
904 # Don't add private logs to RC!
905 if ( isset( $logRestrictions[
$type] ) && $logRestrictions[
$type] !=
'*' ) {
908 $rc = self::newLogEntry( $timestamp,
909 $logPage, $user, $actionComment, $ip,
$type, $action,
910 $target, $logComment, $params, $newId, $actionCommentIRC );
938 $logPage, $user, $actionComment, $ip,
939 $type, $action, $target, $logComment, $params, $newId = 0, $actionCommentIRC =
'',
940 $revId = 0, $isPatrollable =
false, $forceBotFlag =
null, $deleted = 0
943 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
945 # # Get pageStatus for email notification
946 switch (
$type .
'-' . $action ) {
947 case 'delete-delete':
948 case 'delete-delete_redir':
949 case 'delete-delete_redir2':
950 $pageStatus =
'deleted';
953 case 'move-move_redir':
954 $pageStatus =
'moved';
956 case 'delete-restore':
957 $pageStatus =
'restored';
959 case 'upload-upload':
960 $pageStatus =
'created';
962 case 'upload-overwrite':
964 $pageStatus =
'changed';
969 $canAutopatrol = $permissionManager->userHasRight( $user,
'autopatrol' );
970 $markPatrolled = $isPatrollable ? $canAutopatrol :
true;
973 $pageId = $target->getId();
978 if ( $forceBotFlag !==
null ) {
979 $bot = (int)$forceBotFlag;
981 $bot = $permissionManager->userHasRight( $user,
'bot' ) ?
986 $rc->mPage = $target;
987 $rc->mPerformer = $user;
989 'rc_timestamp' => $timestamp,
990 'rc_namespace' => $target->getNamespace(),
991 'rc_title' => $target->getDBkey(),
993 'rc_source' => self::SRC_LOG,
995 'rc_cur_id' => $pageId,
996 'rc_user' => $user->getId(),
997 'rc_user_text' => $user->getName(),
998 'rc_comment' => &$logComment,
999 'rc_comment_text' => &$logComment,
1000 'rc_comment_data' =>
null,
1001 'rc_this_oldid' => (int)$revId,
1002 'rc_last_oldid' => 0,
1004 'rc_ip' => self::checkIPAddress( $ip ),
1005 'rc_patrolled' => $markPatrolled ? self::PRC_AUTOPATROLLED : self::PRC_UNPATROLLED,
1006 'rc_new' => 0, # obsolete
1007 'rc_old_len' =>
null,
1008 'rc_new_len' =>
null,
1009 'rc_deleted' => $deleted,
1010 'rc_logid' => $newId,
1011 'rc_log_type' =>
$type,
1012 'rc_log_action' => $action,
1013 'rc_params' => $params
1017 $formatter = MediaWikiServices::getInstance()->getTitleFormatter();
1023 'prefixedDBkey' => $formatter->getPrefixedDBkey( $logPage ),
1024 'lastTimestamp' => 0,
1025 'actionComment' => $actionComment,
1026 'pageStatus' => $pageStatus,
1027 'actionCommentIRC' => $actionCommentIRC
1069 $categoryWikiPage = MediaWikiServices::getInstance()->getWikiPageFactory()
1070 ->newFromTitle( $categoryTitle );
1072 '@phan-var WikiCategoryPage $categoryWikiPage';
1074 'hidden-cat' => $categoryWikiPage->isHidden()
1076 if ( $added !==
null ) {
1077 $params[
'added'] = $added;
1082 $user = MediaWikiServices::getInstance()->getActorStore()->getUnknownActor();
1086 $rc->mPage = $categoryTitle;
1087 $rc->mPerformer = $user;
1089 'rc_timestamp' => MWTimestamp::convert( TS_MW, $timestamp ),
1091 'rc_title' => $categoryTitle->
getDBkey(),
1093 'rc_source' => self::SRC_CATEGORIZE,
1097 'rc_cur_id' => $pageTitle->
getId(),
1098 'rc_user' => $user->
getId(),
1099 'rc_user_text' => $user->
getName(),
1100 'rc_comment' => &$comment,
1101 'rc_comment_text' => &$comment,
1102 'rc_comment_data' =>
null,
1103 'rc_this_oldid' => (int)$newRevId,
1104 'rc_last_oldid' => $oldRevId,
1105 'rc_bot' => $bot ? 1 : 0,
1106 'rc_ip' => self::checkIPAddress( $ip ),
1107 'rc_patrolled' => self::PRC_AUTOPATROLLED,
1108 'rc_new' => 0, # obsolete
1109 'rc_old_len' =>
null,
1110 'rc_new_len' =>
null,
1111 'rc_deleted' => $deleted,
1113 'rc_log_type' =>
null,
1114 'rc_log_action' =>
'',
1119 $formatter = MediaWikiServices::getInstance()->getTitleFormatter();
1122 'prefixedDBkey' => $formatter->getPrefixedDBkey( $categoryTitle ),
1123 'lastTimestamp' => $lastTimestamp,
1126 'pageStatus' =>
'changed'
1141 $params = $this->parseParams();
1142 return $params[$name] ??
null;
1151 $this->mAttribs = get_object_vars( $row );
1152 $this->mAttribs[
'rc_timestamp'] =
wfTimestamp( TS_MW, $this->mAttribs[
'rc_timestamp'] );
1154 $this->mAttribs[
'rc_deleted'] = $row->rc_deleted;
1156 $comment = CommentStore::getStore()
1160 $this->mAttribs[
'rc_comment'] = &$comment;
1161 $this->mAttribs[
'rc_comment_text'] = &$comment;
1162 $this->mAttribs[
'rc_comment_data'] =
null;
1164 $this->mPerformer = $this->getUserIdentityFromAnyId(
1165 $row->rc_user ??
null,
1166 $row->rc_user_text ??
null,
1167 $row->rc_actor ??
null
1169 $this->mAttribs[
'rc_user'] = $this->mPerformer->getId();
1170 $this->mAttribs[
'rc_user_text'] = $this->mPerformer->getName();
1173 if ( isset( $row->we_expiry ) && $row->we_expiry ) {
1174 $this->watchlistExpiry =
wfTimestamp( TS_MW, $row->we_expiry );
1185 if ( $name ===
'rc_comment' ) {
1186 return CommentStore::getStore()
1187 ->getComment(
'rc_comment', $this->mAttribs,
true )->text;
1190 if ( $name ===
'rc_user' || $name ===
'rc_user_text' || $name ===
'rc_actor' ) {
1191 $user = $this->getPerformerIdentity();
1193 if ( $name ===
'rc_user' ) {
1194 return $user->getId();
1196 if ( $name ===
'rc_user_text' ) {
1197 return $user->getName();
1199 if ( $name ===
'rc_actor' ) {
1202 $actorStore = MediaWikiServices::getInstance()->getActorStore();
1204 return $actorStore->findActorId( $user, $db );
1208 return $this->mAttribs[$name] ??
null;
1215 return $this->mAttribs;
1225 if ( $this->mAttribs[
'rc_type'] ==
RC_EDIT ) {
1226 $trail =
"curid=" . (int)( $this->mAttribs[
'rc_cur_id'] ) .
1227 "&oldid=" . (int)( $this->mAttribs[
'rc_last_oldid'] );
1229 $trail .=
'&diff=0';
1231 $trail .=
'&diff=' . (int)( $this->mAttribs[
'rc_this_oldid'] );
1249 $old = $this->mAttribs[
'rc_old_len'];
1252 $new = $this->mAttribs[
'rc_new_len'];
1254 if ( $old ===
null || $new ===
null ) {
1258 return ChangesList::showCharacterDifference( $old, $new );
1261 private static function checkIPAddress( $ip ) {
1264 if ( !IPUtils::isIPAddress( $ip ) ) {
1265 throw new MWException(
"Attempt to write \"" . $ip .
1266 "\" as an IP address into recent changes" );
1289 MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::RCMaxAge );
1291 return (
int)
wfTimestamp( TS_UNIX, $timestamp ) > time() - $tolerance - $rcMaxAge;
1302 $rcParams = $this->getAttribute(
'rc_params' );
1304 AtEase::suppressWarnings();
1306 AtEase::restoreWarnings();
1308 return $unserializedParams;
1320 if ( is_string( $tags ) ) {
1321 $this->tags[] = $tags;
1323 $this->tags = array_merge( $tags, $this->tags );
1335 $this->editResult = $editResult;
1345 private function getUserIdentityFromAnyId(
1352 $userId = isset( $userId ) ? (int)$userId : null;
1353 $actorId = isset( $actorId ) ? (int)$actorId : 0;
1355 $actorStore = MediaWikiServices::getInstance()->getActorStore();
1356 if ( $userName && $actorId ) {
1359 return $actorStore->newActorFromRowFields( $userId, $userName, $actorId );
1361 if ( $userId !==
null ) {
1362 if ( $userName !==
null ) {
1366 $user = $actorStore->getUserIdentityByUserId( $userId );
1369 throw new RuntimeException(
"User not found by ID: $userId" );
1372 } elseif ( $actorId > 0 ) {
1374 $user = $actorStore->getActorById( $actorId, $db );
1377 throw new RuntimeException(
"User not found by actor ID: $actorId" );
1379 } elseif ( $userName !==
null ) {
1380 $user = $actorStore->getUserIdentityByName( $userName );
1383 throw new RuntimeException(
"User not found by name: $userName" );
1386 throw new RuntimeException(
'At least one of user ID, actor ID or user name must be given' );
unserialize( $serialized)
deprecatePublicPropertyFallback(string $property, string $version, $getter, $setter=null, $class=null, $component=null)
Mark a removed public property as deprecated and provide fallback getter and setter callables.
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
wfDeprecatedMsg( $msg, $version=false, $component=false, $callerOffset=2)
Log a deprecation warning with arbitrary message text.
wfTimestamp( $outputtype=TS_UNIX, $ts=0)
Get a timestamp string in one of various formats.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
if(!defined('MW_SETUP_CALLBACK'))
The persistent session ID (if any) loaded at startup.
This module processes the email notifications when the current page is changed.
A class containing constants representing the names of configuration variables.
static record( $rc, $auto, UserIdentity $user, $tags=null)
Record a log event for a change being patrolled.
static factory(array $params)
Utility class for creating new RC entries.
static getEngine( $uri, $params=[])
static parseToRCType( $type)
Parsing text to RC_* constants.
setEditResult(?EditResult $editResult)
Sets the EditResult associated with the edit.
static newLogEntry( $timestamp, $logPage, $user, $actionComment, $ip, $type, $action, $target, $logComment, $params, $newId=0, $actionCommentIRC='', $revId=0, $isPatrollable=false, $forceBotFlag=null, $deleted=0)
static notifyEdit( $timestamp, $page, $minor, $user, $comment, $oldId, $lastTimestamp, $bot, $ip='', $oldSize=0, $newSize=0, $newId=0, $patrol=0, $tags=[], EditResult $editResult=null)
Makes an entry in the database corresponding to an edit.
reallyMarkPatrolled()
Mark this RecentChange patrolled, without error checking.
static newForCategorization( $timestamp, PageIdentity $categoryTitle, ?UserIdentity $user, $comment, PageIdentity $pageTitle, $oldRevId, $newRevId, $lastTimestamp, $bot, $ip='', $deleted=0, $added=null)
Constructs a RecentChange object for the given categorization This does not call save() on the object...
doMarkPatrolled(Authority $performer, $auto=false, $tags=null)
Mark this RecentChange as patrolled.
parseParams()
Parses and returns the rc_params attribute.
getPerformer()
Get the User object of the person who performed this change.
static notifyNew( $timestamp, $page, $minor, $user, $comment, $bot, $ip='', $size=0, $newId=0, $patrol=0, $tags=[])
Makes an entry in the database corresponding to page creation.
static getChangeTypes()
Get an array of all change types.
static isInRCLifespan( $timestamp, $tolerance=0)
Check whether the given timestamp is new enough to have a RC row with a given tolerance as the recent...
int $counter
Line number of recent change.
save( $send=self::SEND_FEED)
Writes the data in this object to the database.
static getQueryInfo()
Return the tables, fields, and join conditions to be selected to create a new recentchanges object.
static newFromConds( $conds, $fname=__METHOD__, $dbType=DB_REPLICA)
Find the first recent change matching some specific conditions.
getCharacterDifference( $old=0, $new=0)
Returns the change size (HTML).
static parseFromRCType( $rcType)
Parsing RC_* constants to human-readable test.
notifyRCFeeds(array $feeds=null)
Notify all the feeds about the change.
getPerformerIdentity()
Get the UserIdentity of the client that performed this change.
getParam( $name)
Get a parameter value.
addTags( $tags)
Tags to append to the recent change, and associated revision/log.
loadFromRow( $row)
Initialises the members of this object from a mysql row object.
static notifyLog( $timestamp, $logPage, $user, $actionComment, $ip, $type, $action, $target, $logComment, $params, $newId=0, $actionCommentIRC='')
getAttribute( $name)
Get an attribute value.
string null $watchlistExpiry
The expiry time, if this is a temporary watchlist item.
diffLinkTrail( $forceCur)
Gets the end part of the diff URL associated with this object Blank if no diff link should be display...
static newFromId( $rcid)
Obtain the recent change with a given rc_id value.
This is to display changes made to all articles linked in an article.
Represents a title within MediaWiki.
static newFromIdentity(UserIdentity $identity)
Returns a User object corresponding to the given UserIdentity.
Interface for objects (potentially) representing an editable wiki page.
getId( $wikiId=self::LOCAL)
Returns the page ID.
canExist()
Checks whether this PageIdentity represents a "proper" page, meaning that it could exist as an editab...