MediaWiki REL1_37
EditResultBuilder.php
Go to the documentation of this file.
1<?php
25namespace MediaWiki\Storage;
26
30
38
39 public const CONSTRUCTOR_OPTIONS = [
40 'ManualRevertSearchRadius',
41 ];
42
48 EditResult::REVERT_UNDO => 'mw-undo',
49 EditResult::REVERT_ROLLBACK => 'mw-rollback',
50 EditResult::REVERT_MANUAL => 'mw-manual-revert'
51 ];
52
54 private $revisionRecord = null;
55
57 private $isNew = false;
58
60 private $originalRevisionId = false;
61
63 private $originalRevision = null;
64
66 private $revertMethod = null;
67
69 private $newestRevertedRevId = null;
70
72 private $oldestRevertedRevId = null;
73
76
79
81 private $options;
82
89 public function __construct(
91 array $softwareTags,
93 ) {
94 $options->assertRequiredOptions( self::CONSTRUCTOR_OPTIONS );
95
96 $this->revisionStore = $revisionStore;
97 $this->softwareTags = $softwareTags;
98 $this->options = $options;
99 }
100
104 public function buildEditResult(): EditResult {
105 if ( $this->revisionRecord === null ) {
106 throw new PageUpdateException(
107 'Revision was not set prior to building an EditResult'
108 );
109 }
110
111 // do a last-minute check if this was a manual revert
112 $this->detectManualRevert();
113
114 return new EditResult(
115 $this->isNew,
116 $this->originalRevisionId,
117 $this->revertMethod,
118 $this->oldestRevertedRevId,
119 $this->newestRevertedRevId,
120 $this->isExactRevert(),
121 $this->isNullEdit(),
122 $this->getRevertTags()
123 );
124 }
125
132 public function setRevisionRecord( RevisionRecord $revisionRecord ) {
133 $this->revisionRecord = $revisionRecord;
134 }
135
142 public function setIsNew( bool $isNew ) {
143 $this->isNew = $isNew;
144 }
145
156 public function markAsRevert(
157 int $revertMethod,
158 int $oldestRevertedRevId,
159 int $newestRevertedRevId = 0
160 ) {
161 if ( $oldestRevertedRevId === 0 ) {
162 return;
163 }
164 if ( $newestRevertedRevId === 0 ) {
165 $newestRevertedRevId = $oldestRevertedRevId;
166 }
167
168 $this->revertMethod = $revertMethod;
169 $this->oldestRevertedRevId = $oldestRevertedRevId;
170 $this->newestRevertedRevId = $newestRevertedRevId;
171 }
172
178 public function setOriginalRevisionId( $originalRevId ) {
179 $this->originalRevisionId = $originalRevId;
180 }
181
189 private function detectManualRevert() {
190 $searchRadius = $this->options->get( 'ManualRevertSearchRadius' );
191 if ( !$searchRadius ||
192 // we already marked this as a revert
193 $this->revertMethod !== null ||
194 // it's a null edit, nothing was reverted
195 $this->isNullEdit() ||
196 // we wouldn't be able to figure out what was the newest reverted edit
197 // this also discards new pages
198 !$this->revisionRecord->getParentId()
199 ) {
200 return;
201 }
202
203 $revertedToRev = $this->revisionStore->findIdenticalRevision( $this->revisionRecord, $searchRadius );
204 if ( !$revertedToRev ) {
205 return;
206 }
207 $oldestReverted = $this->revisionStore->getNextRevision(
208 $revertedToRev,
209 RevisionStore::READ_LATEST
210 );
211 if ( !$oldestReverted ) {
212 return;
213 }
214
215 $this->setOriginalRevisionId( $revertedToRev->getId() );
216 $this->markAsRevert(
218 $oldestReverted->getId(),
219 $this->revisionRecord->getParentId()
220 );
221 }
222
231 private function getOriginalRevision(
232 int $flags = RevisionStore::READ_NORMAL
233 ): ?RevisionRecord {
234 if ( $this->originalRevision ) {
235 return $this->originalRevision;
236 }
237 if ( $this->originalRevisionId === false ) {
238 return null;
239 }
240
241 $this->originalRevision = $this->revisionStore->getRevisionById(
242 $this->originalRevisionId,
243 $flags
244 );
245 return $this->originalRevision;
246 }
247
254 private function isExactRevert(): bool {
255 if ( $this->isNew || $this->oldestRevertedRevId === null ) {
256 return false;
257 }
258
259 if ( $this->getOriginalRevision() === null ) {
260 // we can't find the original revision for some reason, better return false
261 return false;
262 }
263
264 return $this->revisionRecord->hasSameContent( $this->getOriginalRevision() );
265 }
266
272 private function isNullEdit(): bool {
273 if ( $this->isNew ) {
274 return false;
275 }
276
277 return $this->getOriginalRevision() &&
278 $this->originalRevisionId === $this->revisionRecord->getParentId();
279 }
280
286 private function getRevertTags(): array {
287 if ( isset( self::REVERT_METHOD_TO_CHANGE_TAG[$this->revertMethod] ) ) {
288 $revertTag = self::REVERT_METHOD_TO_CHANGE_TAG[$this->revertMethod];
289 if ( in_array( $revertTag, $this->softwareTags ) ) {
290 return [ $revertTag ];
291 }
292 }
293 return [];
294 }
295}
if(ini_get('mbstring.func_overload')) if(!defined('MW_ENTRY_POINT'))
Pre-config setup: Before loading LocalSettings.php.
Definition Setup.php:88
A class for passing options to services.
assertRequiredOptions(array $expectedKeys)
Assert that the list of options provided in this instance exactly match $expectedKeys,...
Page revision base class.
Service for looking up page revisions.
Builder class for the EditResult object.
setOriginalRevisionId( $originalRevId)
Sets the ID of an earlier revision that is being repeated or restored.
setIsNew(bool $isNew)
Set whether the edit created a new page.
detectManualRevert()
If this edit was not already marked as a revert using EditResultBuilder::markAsRevert(),...
__construct(RevisionStore $revisionStore, array $softwareTags, ServiceOptions $options)
isExactRevert()
Whether the edit was an exact revert, i.e.
setRevisionRecord(RevisionRecord $revisionRecord)
Set the revision associated with this edit.
markAsRevert(int $revertMethod, int $oldestRevertedRevId, int $newestRevertedRevId=0)
Marks this edit as a revert and applies relevant information.
getRevertTags()
Returns an array of revert-related tags that will be applied automatically to this edit.
isNullEdit()
An edit is a null edit if the original revision is equal to the parent revision.
getOriginalRevision(int $flags=RevisionStore::READ_NORMAL)
Returns the revision that is being repeated or restored.
const REVERT_METHOD_TO_CHANGE_TAG
A mapping from EditResult's revert methods to relevant change tags.
Object for storing information about the effects of an edit.
Exception representing a failure to update a page entry.