Go to the documentation of this file.
50 use Wikimedia\Assert\Assert;
198 $this->rcPatrolStatus =
$status;
209 $this->usePageCreationLog = $use;
230 return $this->loadBalancer->getConnectionRef( $mode, [], $this->
getWikiId() );
238 return $this->wikiPage->getTitle();
246 return $this->wikiPage->getTitle();
292 $parentId = $parent ? $parent->getId() : 0;
294 return $parentId !== $expectedParentRevision;
325 return $this->derivedDataUpdater->grabCurrentRevision();
351 $this->slotsUpdate->modifyContent( $role,
$content );
362 $this->slotsUpdate->modifySlot( $slot );
385 $this->slotsUpdate->modifySlot( $inheritedSlot );
400 $this->slotsUpdate->removeSlot( $role );
425 Assert::parameterType(
'integer|boolean',
$originalRevId,
'$originalRevId' );
447 Assert::parameterType(
'integer',
$undidRevId,
'$undidRevId' );
458 Assert::parameterType(
'string', $tag,
'$tag' );
459 $this->tags[] = trim( $tag );
469 Assert::parameterElementType(
'string',
$tags,
'$tags' );
470 foreach (
$tags as $tag ) {
491 foreach ( $this->slotsUpdate->getModifiedRoles() as $role ) {
495 $content = $this->slotsUpdate->getModifiedSlot( $role )->getContent();
498 $tag = $handler->getChangeTag( $old_content,
$content, $flags );
510 return array_unique(
$tags );
523 if ( $parent && $parent->hasSlot( $role ) ) {
536 if ( $this->slotsUpdate->isModifiedSlot( $role ) ) {
537 $slot = $this->slotsUpdate->getModifiedSlot( $role );
557 if ( !$this->useAutomaticEditSummaries || ( $flags &
EDIT_AUTOSUMMARY ) === 0 ) {
564 $roles = $this->slotsUpdate->getModifiedRoles();
565 $role = reset( $roles );
567 if ( $role ===
false ) {
572 $content = $this->slotsUpdate->getModifiedSlot( $role )->getContent();
574 $summary = $handler->getAutosummary( $old_content,
$content, $flags );
627 Assert::parameterType(
'integer', $flags,
'$flags' );
630 throw new RuntimeException(
'saveRevision() has already been called on this PageUpdater!' );
635 throw new RuntimeException(
'Something is trying to edit an article with an empty title' );
641 $this->slotsUpdate->getModifiedRoles(),
645 $this->slotsUpdate->getRemovedRoles(),
654 foreach ( $this->slotsUpdate->getModifiedRoles() as $role ) {
655 $slot = $this->slotsUpdate->getModifiedSlot( $role );
656 $roleHandler = $this->slotRoleRegistry->getRoleHandler( $role );
658 if ( !$roleHandler->isAllowedModel( $slot->getModel(), $this->
getTitle() ) ) {
662 $this->
getTitle()->getPrefixedText(),
663 wfMessage( $roleHandler->getNameMessageKey() )
691 $this->derivedDataUpdater->prepareContent(
725 $this->derivedDataUpdater->getCanonicalParserOutput();
727 $mainContent = $this->derivedDataUpdater->getSlots()->getContent(
SlotRecord::MAIN );
734 $flags &
EDIT_MINOR,
null,
null, &$flags, &$hookStatus ];
736 if ( !
Hooks::run(
'PageContentSave', $hook_args ) ) {
737 if ( $hookStatus->isOK() ) {
739 $hookStatus->fatal(
'edit-hook-aborted' );
742 $this->status = $hookStatus;
749 if ( $summary->text ===
'' && $summary->data ===
null ) {
772 return ( $this->status && $this->status->isOK() )
773 ? $this->status->value[
'revision-record']
783 return $this->status !==
null;
819 return $this->status && $this->status->isOK();
828 return $this->status && $this->status->isOK() && $this->status->value[
'new'];
840 && $this->status->isOK()
841 && $this->status->value[
'revision-record'] ===
null;
851 return ( $this->status && $this->status->isOK() )
852 ? $this->status->value[
'revision-record']
884 $rev = $this->derivedDataUpdater->getRevision();
885 '@phan-var MutableRevisionRecord $rev';
887 $rev->setPageId(
$title->getArticleID() );
890 $oldid = $parent->getId();
891 $rev->setParentId( $oldid );
896 $rev->setComment( $comment );
897 $rev->setUser(
$user );
898 $rev->setMinorEdit( ( $flags &
EDIT_MINOR ) > 0 );
900 foreach ( $rev->getSlots()->getSlots() as $slot ) {
913 $rev->getSlotRoles(),
935 $oldid = $oldRev ? $oldRev->getId() : 0;
955 $now = $newRevisionRecord->getTimestamp();
958 $changed = $this->derivedDataUpdater->isChange();
963 $dbw->startAtomic( __METHOD__ );
969 if ( $latestNow != $oldid ) {
973 $dbw->endAtomic( __METHOD__ );
986 $newRevisionRecord = $this->revisionStore->insertRevisionOn( $newRevisionRecord, $dbw );
987 $newLegacyRevision =
new Revision( $newRevisionRecord );
991 $wasRedirect = $this->derivedDataUpdater->wasRedirect();
999 'NewRevisionFromEditComplete',
1009 $newRevisionRecord->isMinor(),
1013 $newRevisionRecord->getTimestamp(),
1017 $newRevisionRecord->getSize(),
1018 $newRevisionRecord->getId(),
1026 $dbw->endAtomic( __METHOD__ );
1029 $status->value[
'revision-record'] = $newRevisionRecord;
1032 $status->value[
'revision'] = $newLegacyRevision;
1038 $newRevisionRecord = $oldRev;
1044 $this->
getTitle()->invalidateCache( $now );
1062 [
'changed' => $changed, ]
1082 if ( !$this->derivedDataUpdater->getSlots()->hasSlot(
SlotRecord::MAIN ) ) {
1099 $now = $newRevisionRecord->getTimestamp();
1102 $dbw->startAtomic( __METHOD__ );
1107 if ( $newid ===
false ) {
1108 $dbw->endAtomic( __METHOD__ );
1118 $newRevisionRecord->setPageId( $newid );
1121 $newRevisionRecord = $this->revisionStore->insertRevisionOn( $newRevisionRecord, $dbw );
1122 $newLegacyRevision =
new Revision( $newRevisionRecord );
1133 'NewRevisionFromEditComplete',
1143 $newRevisionRecord->isMinor(),
1148 $newRevisionRecord->getSize(),
1149 $newRevisionRecord->getId(),
1157 if ( $this->usePageCreationLog ) {
1161 $logEntry->setPerformer(
$user );
1162 $logEntry->setTarget( $this->
getTitle() );
1163 $logEntry->setComment( $summary->text );
1164 $logEntry->setTimestamp( $now );
1165 $logEntry->setAssociatedRevId( $newRevisionRecord->getId() );
1166 $logEntry->insert();
1172 $dbw->endAtomic( __METHOD__ );
1176 $status->value[
'revision'] = $newLegacyRevision;
1177 $status->value[
'revision-record'] = $newRevisionRecord;
1189 [
'created' =>
true ]
1212 $summary, $flags,
$status, $hints
1215 $hints[
'causeAction'] =
'edit-page';
1218 $newLegacyRevision =
new Revision( $newRevisionRecord );
1222 $this->derivedDataUpdater->prepareUpdate( $newRevisionRecord, $hints );
1223 $this->derivedDataUpdater->doUpdates();
1228 if ( $hints[
'created'] ??
false ) {
1231 $flags &
EDIT_MINOR,
null,
null, &$flags, $newLegacyRevision ];
1232 Hooks::run(
'PageContentInsertComplete', $params );
1237 $flags &
EDIT_MINOR,
null,
null, &$flags, $newLegacyRevision,
1239 Hooks::run(
'PageContentSaveComplete', $params );
1248 return $this->slotRoleRegistry->getRequiredRoles( $this->
getTitle() );
1255 return $this->slotRoleRegistry->getAllowedRoles( $this->
getTitle() );
1260 if ( !in_array( $role, $allowedRoles ) ) {
1267 if ( in_array( $role, $requiredRoles ) ) {
1275 $forbidden = array_diff( $roles, $allowedRoles );
1276 if ( !empty( $forbidden ) ) {
1278 'edit-slots-cannot-add',
1279 count( $forbidden ),
1280 implode(
', ', $forbidden )
1288 $needed = array_diff( $roles, $requiredRoles );
1289 if ( !empty( $needed ) ) {
1291 'edit-slots-cannot-remove',
1293 implode(
', ', $needed )
1301 $missing = array_diff( $requiredRoles, $roles );
1302 if ( !empty( $missing ) ) {
1304 'edit-slots-missing',
1306 implode(
', ', $missing )
addTags(array $tags)
Sets tags to apply to this update.
makeNewRevision(CommentStoreComment $comment, User $user, $flags, Status $status)
Constructs a MutableRevisionRecord based on the Content prepared by the DerivedPageDataUpdater.
A content handler knows how do deal with a specific type of content on a wiki page.
static getForModelID( $modelId)
Returns the ContentHandler singleton for the given model ID.
saveRevision(CommentStoreComment $summary, $flags=0)
Change an existing article or create a new article.
static newFatal( $message,... $parameters)
Factory function for fatal errors.
setUndidRevisionId( $undidRevId)
Sets the ID of revision that was undone by the present update.
setAjaxEditStash( $ajaxEditStash)
doModify(CommentStoreComment $summary, User $user, $flags)
bool $usePageCreationLog
whether to create a log entry for new page creations.
updateRevisionOn( $dbw, $revision, $lastRevision=null, $lastRevIsRedirect=null)
Update the page record to point to a newly saved revision.
__construct(User $user, WikiPage $wikiPage, DerivedPageDataUpdater $derivedDataUpdater, ILoadBalancer $loadBalancer, RevisionStore $revisionStore, SlotRoleRegistry $slotRoleRegistry)
checkNoRolesRequired(array $roles, Status $status)
error( $message,... $parameters)
Add an error, do not set fatal flag This can be used for non-fatal errors.
inheritSlot(SlotRecord $originalSlot)
Explicitly inherit a slot from some earlier revision.
incEditCount()
Schedule a deferred update to update the user's edit count.
setOriginalRevisionId( $originalRevId)
Sets the ID of an earlier revision that is being repeated or restored by this update.
boolean $ajaxEditStash
see $wgAjaxEditStash
Utility class for creating new RC entries.
boolean $useAutomaticEditSummaries
see $wgUseAutomaticEditSummaries
getExplicitTags()
Returns the list of tags set using the addTag() method.
warning( $message,... $parameters)
Add a new warning.
static addUpdate(DeferrableUpdate $update, $stage=self::POSTSEND)
Add an update to the deferred list to be run later by execute()
Class representing a MediaWiki article and history.
fatal( $message,... $parameters)
Add an error and set OK to false, indicating that the operation as a whole was fatal.
setUsePageCreationLog( $use)
Whether to create a log entry for new page creations.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
getParentContent( $role)
Returns the content of the given slot of the parent revision, with no audience checks applied.
ILoadBalancer $loadBalancer
wasCommitted()
Whether saveRevision() has been called on this instance.
getOriginalRevisionId()
Returns the ID of an earlier revision that is being repeated or restored by this update.
ensureRoleAllowed( $role)
Generic operation result class Has warning/error list, boolean status and arbitrary value.
doCreate(CommentStoreComment $summary, User $user, $flags)
RevisionStore $revisionStore
checkFlags( $flags)
Check flags and add EDIT_NEW or EDIT_UPDATE to them as needed.
wasSuccessful()
Whether saveRevision() completed successfully.
setContent( $role, Content $content)
Set the new content for the given slot role.
isOK()
Returns whether the operation completed.
insertOn( $dbw, $pageId=null)
Insert a new empty page record for this article.
Class for managing the deferred updates.
getNewRevision()
The new revision created by saveRevision(), or null if saveRevision() has not yet been called,...
computeEffectiveTags( $flags)
getAtomicSectionUpdate(IDatabase $dbw, WikiPage $wikiPage, RevisionRecord $newRevisionRecord, User $user, CommentStoreComment $summary, $flags, Status $status, $hints=[])
static notifyEdit( $timestamp, $title, $minor, $user, $comment, $oldId, $lastTimestamp, $bot, $ip='', $oldSize=0, $newSize=0, $newId=0, $patrol=0, $tags=[])
Makes an entry in the database corresponding to an edit.
merge( $other, $overwriteValue=false)
Merge another status object into this one.
removeSlot( $role)
Removes the slot with the given role.
lockAndGetLatest()
Lock the page row for this title+id and return page_latest (or 0)
checkAllRolesAllowed(array $roles, Status $status)
addTag( $tag)
Sets a tag to apply to this update.
Deferrable Update for closure/callback updates via IDatabase::doAtomicSection()
static getLocalizedName( $name, Language $lang=null)
Returns the localized name for a given content model.
static newGood( $value=null)
Factory function for good results.
Controller-like object for creating and updating pages by creating new revisions.
getDBConnectionRef( $mode)
hasEditConflict( $expectedParentRevision)
Checks whether this update conflicts with another update performed between the client loading data to...
Base interface for content objects.
RevisionSlotsUpdate $slotsUpdate
Represents a title within MediaWiki.
grabParentRevision()
Returns the revision that was the page's current revision when grabParentRevision() was first called.
static notifyNew( $timestamp, $title, $minor, $user, $comment, $bot, $ip='', $size=0, $newId=0, $patrol=0, $tags=[])
Makes an entry in the database corresponding to page creation Note: the title object must be loaded w...
getStatus()
The Status object indicating whether saveRevision() was successful, or null if saveRevision() was not...
setRcPatrolStatus( $status)
Sets the "patrolled" status of the edit.
int $rcPatrolStatus
the RC patrol status the new revision should be marked with.
ensureRoleNotRequired( $role)
getContentHandler( $role)
getUndidRevisionId()
Returns the revision ID set by setUndidRevisionId(), indicating what revision is being undone by this...
addAutopromoteOnceGroups( $event)
Add the user to the group if he/she meets given criteria.
Class for creating new log entries and inserting them into the database.
DerivedPageDataUpdater $derivedDataUpdater
checkAllRequiredRoles(array $roles, Status $status)
Exception representing a failure to update a page entry.
A handle for managing updates for derived page data on edit, import, purge, etc.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
static addCallableUpdate( $callable, $stage=self::POSTSEND, $dbw=null)
Add a callable update.
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
SlotRoleRegistry $slotRoleRegistry
getName()
Get the user name, or the IP of an anonymous user.
setUseAutomaticEditSummaries( $useAutomaticEditSummaries)
Can be used to enable or disable automatic summaries that are applied to certain kinds of changes,...
isNew()
Whether saveRevision() was called and created a new page.
isUnchanged()
Whether saveRevision() did not create a revision because the content didn't change (null-edit).
setSlot(SlotRecord $slot)
Set the new slot for the given slot role.