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 );
555 MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::RCFeeds );
556 if ( $feeds ===
null ) {
560 $performer = $this->getPerformerIdentity();
562 foreach ( $feeds as $params ) {
564 'omit_bots' =>
false,
565 'omit_anon' =>
false,
566 'omit_user' =>
false,
567 'omit_minor' =>
false,
568 'omit_patrolled' =>
false,
572 ( $params[
'omit_bots'] && $this->mAttribs[
'rc_bot'] ) ||
573 ( $params[
'omit_anon'] && !$performer->isRegistered() ) ||
574 ( $params[
'omit_user'] && $performer->isRegistered() ) ||
575 ( $params[
'omit_minor'] && $this->mAttribs[
'rc_minor'] ) ||
576 ( $params[
'omit_patrolled'] && $this->mAttribs[
'rc_patrolled'] ) ||
582 $actionComment = $this->mExtra[
'actionCommentIRC'] ??
null;
585 $feed->notify( $this, $actionComment );
598 public static function getEngine( $uri, $params = [] ) {
601 MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::RCEngines );
602 $scheme = parse_url( $uri, PHP_URL_SCHEME );
604 throw new MWException(
"Invalid RCFeed uri: '$uri'" );
606 if ( !isset( $rcEngines[$scheme] ) ) {
607 throw new MWException(
"Unknown RCFeed engine: '$scheme'" );
609 if ( defined(
'MW_PHPUNIT_TEST' ) && is_object( $rcEngines[$scheme] ) ) {
610 return $rcEngines[$scheme];
612 return new $rcEngines[$scheme]( $params );
627 $mainConfig = MediaWikiServices::getInstance()->getMainConfig();
628 $useRCPatrol = $mainConfig->get( MainConfigNames::UseRCPatrol );
629 $useNPPatrol = $mainConfig->get( MainConfigNames::UseNPPatrol );
630 $useFilePatrol = $mainConfig->get( MainConfigNames::UseFilePatrol );
632 if ( $tags ===
null ) {
634 } elseif ( is_string( $tags ) ) {
638 $status = PermissionStatus::newEmpty();
641 if ( !$useRCPatrol && ( !$useNPPatrol || $this->getAttribute(
'rc_type' ) !=
RC_NEW ) &&
642 ( !$useFilePatrol || !( $this->getAttribute(
'rc_type' ) ==
RC_LOG &&
643 $this->getAttribute(
'rc_log_type' ) ==
'upload' ) ) ) {
644 $status->fatal(
'rcpatroldisabled' );
648 $user = MediaWikiServices::getInstance()->getUserFactory()->newFromAuthority( $performer );
649 if ( !Hooks::runner()->onMarkPatrolled(
650 $this->getAttribute(
'rc_id' ), $user,
false, $auto, $tags )
652 $status->fatal(
'hookaborted' );
655 if ( $performer->
getUser()->getName() === $this->getAttribute(
'rc_user_text' ) &&
658 $status->fatal(
'markedaspatrollederror-noautopatrol' );
660 if ( !$status->isGood() ) {
661 return $status->toLegacyErrorArray();
664 if ( $this->getAttribute(
'rc_patrolled' ) ) {
668 $this->reallyMarkPatrolled();
672 Hooks::runner()->onMarkPatrolledComplete(
673 $this->getAttribute(
'rc_id' ), $user,
false, $auto );
687 'rc_patrolled' => self::PRC_PATROLLED
690 'rc_id' => $this->getAttribute(
'rc_id' )
696 $this->
getTitle()->invalidateCache();
699 $revisionId = $this->getAttribute(
'rc_this_oldid' );
701 $revertedTagUpdateManager =
702 MediaWikiServices::getInstance()->getRevertedTagUpdateManager();
703 $revertedTagUpdateManager->approveRevertedTagForRevision( $revisionId );
706 return $dbw->affectedRows();
734 $timestamp, $page, $minor, $user, $comment, $oldId, $lastTimestamp,
735 $bot, $ip =
'', $oldSize = 0, $newSize = 0, $newId = 0, $patrol = 0,
738 Assert::parameter( $page->exists(),
'$page',
'must represent an existing page' );
742 $rc->mPerformer = $user;
744 'rc_timestamp' => $timestamp,
745 'rc_namespace' => $page->getNamespace(),
746 'rc_title' => $page->getDBkey(),
748 'rc_source' => self::SRC_EDIT,
749 'rc_minor' => $minor ? 1 : 0,
750 'rc_cur_id' => $page->getId(),
751 'rc_user' => $user->getId(),
752 'rc_user_text' => $user->getName(),
753 'rc_comment' => &$comment,
754 'rc_comment_text' => &$comment,
755 'rc_comment_data' =>
null,
756 'rc_this_oldid' => (int)$newId,
757 'rc_last_oldid' => $oldId,
758 'rc_bot' => $bot ? 1 : 0,
759 'rc_ip' => self::checkIPAddress( $ip ),
760 'rc_patrolled' => intval( $patrol ),
761 'rc_new' => 0, # obsolete
762 'rc_old_len' => $oldSize,
763 'rc_new_len' => $newSize,
766 'rc_log_type' =>
null,
767 'rc_log_action' =>
'',
772 $formatter = MediaWikiServices::getInstance()->getTitleFormatter();
775 'prefixedDBkey' => $formatter->getPrefixedDBkey( $page ),
776 'lastTimestamp' => $lastTimestamp,
777 'oldSize' => $oldSize,
778 'newSize' => $newSize,
779 'pageStatus' =>
'changed'
782 DeferredUpdates::addCallableUpdate(
783 static function () use ( $rc, $tags, $editResult ) {
784 $rc->addTags( $tags );
785 $rc->setEditResult( $editResult );
788 DeferredUpdates::POSTSEND,
816 $page, $minor, $user, $comment, $bot,
817 $ip =
'', $size = 0, $newId = 0, $patrol = 0, $tags = []
819 Assert::parameter( $page->exists(),
'$page',
'must represent an existing page' );
823 $rc->mPerformer = $user;
825 'rc_timestamp' => $timestamp,
826 'rc_namespace' => $page->getNamespace(),
827 'rc_title' => $page->getDBkey(),
829 'rc_source' => self::SRC_NEW,
830 'rc_minor' => $minor ? 1 : 0,
831 'rc_cur_id' => $page->getId(),
832 'rc_user' => $user->getId(),
833 'rc_user_text' => $user->getName(),
834 'rc_comment' => &$comment,
835 'rc_comment_text' => &$comment,
836 'rc_comment_data' =>
null,
837 'rc_this_oldid' => (int)$newId,
838 'rc_last_oldid' => 0,
839 'rc_bot' => $bot ? 1 : 0,
840 'rc_ip' => self::checkIPAddress( $ip ),
841 'rc_patrolled' => intval( $patrol ),
842 'rc_new' => 1, # obsolete
844 'rc_new_len' => $size,
847 'rc_log_type' =>
null,
848 'rc_log_action' =>
'',
853 $formatter = MediaWikiServices::getInstance()->getTitleFormatter();
856 'prefixedDBkey' => $formatter->getPrefixedDBkey( $page ),
857 'lastTimestamp' => 0,
860 'pageStatus' =>
'created'
863 DeferredUpdates::addCallableUpdate(
864 static function () use ( $rc, $tags ) {
865 $rc->addTags( $tags );
868 DeferredUpdates::POSTSEND,
892 $logPage, $user, $actionComment, $ip,
$type,
893 $action, $target, $logComment, $params, $newId = 0, $actionCommentIRC =
''
895 $logRestrictions = MediaWikiServices::getInstance()->getMainConfig()
896 ->get( MainConfigNames::LogRestrictions );
898 # Don't add private logs to RC!
899 if ( isset( $logRestrictions[
$type] ) && $logRestrictions[
$type] !=
'*' ) {
902 $rc = self::newLogEntry( $timestamp,
903 $logPage, $user, $actionComment, $ip,
$type, $action,
904 $target, $logComment, $params, $newId, $actionCommentIRC );
929 $logPage, $user, $actionComment, $ip,
930 $type, $action, $target, $logComment, $params, $newId = 0, $actionCommentIRC =
'',
931 $revId = 0, $isPatrollable =
false ) {
933 $permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
935 # # Get pageStatus for email notification
936 switch (
$type .
'-' . $action ) {
937 case 'delete-delete':
938 case 'delete-delete_redir':
939 case 'delete-delete_redir2':
940 $pageStatus =
'deleted';
943 case 'move-move_redir':
944 $pageStatus =
'moved';
946 case 'delete-restore':
947 $pageStatus =
'restored';
949 case 'upload-upload':
950 $pageStatus =
'created';
952 case 'upload-overwrite':
954 $pageStatus =
'changed';
959 $canAutopatrol = $permissionManager->userHasRight( $user,
'autopatrol' );
960 $markPatrolled = $isPatrollable ? $canAutopatrol :
true;
963 $pageId = $target->getId();
969 $rc->mPage = $target;
970 $rc->mPerformer = $user;
972 'rc_timestamp' => $timestamp,
973 'rc_namespace' => $target->getNamespace(),
974 'rc_title' => $target->getDBkey(),
976 'rc_source' => self::SRC_LOG,
978 'rc_cur_id' => $pageId,
979 'rc_user' => $user->getId(),
980 'rc_user_text' => $user->getName(),
981 'rc_comment' => &$logComment,
982 'rc_comment_text' => &$logComment,
983 'rc_comment_data' =>
null,
984 'rc_this_oldid' => (int)$revId,
985 'rc_last_oldid' => 0,
986 'rc_bot' => $permissionManager->userHasRight( $user,
'bot' ) ?
988 'rc_ip' => self::checkIPAddress( $ip ),
989 'rc_patrolled' => $markPatrolled ? self::PRC_AUTOPATROLLED : self::PRC_UNPATROLLED,
990 'rc_new' => 0, # obsolete
991 'rc_old_len' =>
null,
992 'rc_new_len' =>
null,
994 'rc_logid' => $newId,
995 'rc_log_type' =>
$type,
996 'rc_log_action' => $action,
997 'rc_params' => $params
1001 $formatter = MediaWikiServices::getInstance()->getTitleFormatter();
1007 'prefixedDBkey' => $formatter->getPrefixedDBkey( $logPage ),
1008 'lastTimestamp' => 0,
1009 'actionComment' => $actionComment,
1010 'pageStatus' => $pageStatus,
1011 'actionCommentIRC' => $actionCommentIRC
1053 $categoryWikiPage = MediaWikiServices::getInstance()->getWikiPageFactory()
1054 ->newFromTitle( $categoryTitle );
1056 '@phan-var WikiCategoryPage $categoryWikiPage';
1058 'hidden-cat' => $categoryWikiPage->isHidden()
1060 if ( $added !==
null ) {
1061 $params[
'added'] = $added;
1066 $user = MediaWikiServices::getInstance()->getActorStore()->getUnknownActor();
1070 $rc->mPage = $categoryTitle;
1071 $rc->mPerformer = $user;
1073 'rc_timestamp' => MWTimestamp::convert( TS_MW, $timestamp ),
1075 'rc_title' => $categoryTitle->
getDBkey(),
1077 'rc_source' => self::SRC_CATEGORIZE,
1081 'rc_cur_id' => $pageTitle->
getId(),
1082 'rc_user' => $user->
getId(),
1083 'rc_user_text' => $user->
getName(),
1084 'rc_comment' => &$comment,
1085 'rc_comment_text' => &$comment,
1086 'rc_comment_data' =>
null,
1087 'rc_this_oldid' => (int)$newRevId,
1088 'rc_last_oldid' => $oldRevId,
1089 'rc_bot' => $bot ? 1 : 0,
1090 'rc_ip' => self::checkIPAddress( $ip ),
1091 'rc_patrolled' => self::PRC_AUTOPATROLLED,
1092 'rc_new' => 0, # obsolete
1093 'rc_old_len' =>
null,
1094 'rc_new_len' =>
null,
1095 'rc_deleted' => $deleted,
1097 'rc_log_type' =>
null,
1098 'rc_log_action' =>
'',
1103 $formatter = MediaWikiServices::getInstance()->getTitleFormatter();
1106 'prefixedDBkey' => $formatter->getPrefixedDBkey( $categoryTitle ),
1107 'lastTimestamp' => $lastTimestamp,
1110 'pageStatus' =>
'changed'
1125 $params = $this->parseParams();
1126 return $params[$name] ??
null;
1135 $this->mAttribs = get_object_vars( $row );
1136 $this->mAttribs[
'rc_timestamp'] =
wfTimestamp( TS_MW, $this->mAttribs[
'rc_timestamp'] );
1138 $this->mAttribs[
'rc_deleted'] = $row->rc_deleted;
1140 $comment = CommentStore::getStore()
1144 $this->mAttribs[
'rc_comment'] = &$comment;
1145 $this->mAttribs[
'rc_comment_text'] = &$comment;
1146 $this->mAttribs[
'rc_comment_data'] =
null;
1148 $this->mPerformer = $this->getUserIdentityFromAnyId(
1149 $row->rc_user ??
null,
1150 $row->rc_user_text ??
null,
1151 $row->rc_actor ??
null
1153 $this->mAttribs[
'rc_user'] = $this->mPerformer->getId();
1154 $this->mAttribs[
'rc_user_text'] = $this->mPerformer->getName();
1157 if ( isset( $row->we_expiry ) && $row->we_expiry ) {
1158 $this->watchlistExpiry =
wfTimestamp( TS_MW, $row->we_expiry );
1169 if ( $name ===
'rc_comment' ) {
1170 return CommentStore::getStore()
1171 ->getComment(
'rc_comment', $this->mAttribs,
true )->text;
1174 if ( $name ===
'rc_user' || $name ===
'rc_user_text' || $name ===
'rc_actor' ) {
1175 $user = $this->getPerformerIdentity();
1177 if ( $name ===
'rc_user' ) {
1178 return $user->getId();
1180 if ( $name ===
'rc_user_text' ) {
1181 return $user->getName();
1183 if ( $name ===
'rc_actor' ) {
1186 $actorStore = MediaWikiServices::getInstance()->getActorStore();
1188 return $actorStore->findActorId( $user, $db );
1192 return $this->mAttribs[$name] ??
null;
1199 return $this->mAttribs;
1209 if ( $this->mAttribs[
'rc_type'] ==
RC_EDIT ) {
1210 $trail =
"curid=" . (int)( $this->mAttribs[
'rc_cur_id'] ) .
1211 "&oldid=" . (int)( $this->mAttribs[
'rc_last_oldid'] );
1213 $trail .=
'&diff=0';
1215 $trail .=
'&diff=' . (int)( $this->mAttribs[
'rc_this_oldid'] );
1233 $old = $this->mAttribs[
'rc_old_len'];
1236 $new = $this->mAttribs[
'rc_new_len'];
1238 if ( $old ===
null || $new ===
null ) {
1242 return ChangesList::showCharacterDifference( $old, $new );
1245 private static function checkIPAddress( $ip ) {
1248 if ( !IPUtils::isIPAddress( $ip ) ) {
1249 throw new MWException(
"Attempt to write \"" . $ip .
1250 "\" as an IP address into recent changes" );
1273 MediaWikiServices::getInstance()->getMainConfig()->get( MainConfigNames::RCMaxAge );
1275 return (
int)
wfTimestamp( TS_UNIX, $timestamp ) > time() - $tolerance - $rcMaxAge;
1286 $rcParams = $this->getAttribute(
'rc_params' );
1288 AtEase::suppressWarnings();
1290 AtEase::restoreWarnings();
1292 return $unserializedParams;
1304 if ( is_string( $tags ) ) {
1305 $this->tags[] = $tags;
1307 $this->tags = array_merge( $tags, $this->tags );
1319 $this->editResult = $editResult;
1329 private function getUserIdentityFromAnyId(
1336 $userId = isset( $userId ) ? (int)$userId : null;
1337 $actorId = isset( $actorId ) ? (int)$actorId : 0;
1339 $actorStore = MediaWikiServices::getInstance()->getActorStore();
1340 if ( $userName && $actorId ) {
1343 return $actorStore->newActorFromRowFields( $userId, $userName, $actorId );
1345 if ( $userId !==
null ) {
1346 if ( $userName !==
null ) {
1350 $user = $actorStore->getUserIdentityByUserId( $userId );
1353 throw new RuntimeException(
"User not found by ID: $userId" );
1356 } elseif ( $actorId > 0 ) {
1358 $user = $actorStore->getActorById( $actorId, $db );
1361 throw new RuntimeException(
"User not found by actor ID: $actorId" );
1363 } elseif ( $userName !==
null ) {
1364 $user = $actorStore->getUserIdentityByName( $userName );
1367 throw new RuntimeException(
"User not found by name: $userName" );
1370 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 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.
static newLogEntry( $timestamp, $logPage, $user, $actionComment, $ip, $type, $action, $target, $logComment, $params, $newId=0, $actionCommentIRC='', $revId=0, $isPatrollable=false)
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...