34use Wikimedia\Assert\Assert;
35use Wikimedia\AtEase\AtEase;
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.
trait DeprecationHelper
Use this trait in classes which have properties for which public access is deprecated or implementati...
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...