Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
41 / 41 |
|
100.00% |
13 / 13 |
CRAP | |
100.00% |
1 / 1 |
EditResult | |
100.00% |
41 / 41 |
|
100.00% |
13 / 13 |
15 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
1 | |||
newFromArray | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
1 | |||
getNewestRevertedRevisionId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getOldestRevertedRevisionId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getUndidRevId | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
getOriginalRevisionId | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isNew | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isRevert | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
2 | |||
getRevertMethod | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isExactRevert | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
isNullEdit | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRevertTags | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
jsonSerialize | |
100.00% |
11 / 11 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * This program is free software; you can redistribute it and/or modify |
4 | * it under the terms of the GNU General Public License as published by |
5 | * the Free Software Foundation; either version 2 of the License, or |
6 | * (at your option) any later version. |
7 | * |
8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | * GNU General Public License for more details. |
12 | * |
13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
16 | * http://www.gnu.org/copyleft/gpl.html |
17 | * |
18 | * @file |
19 | */ |
20 | |
21 | namespace MediaWiki\Storage; |
22 | |
23 | use JsonSerializable; |
24 | |
25 | /** |
26 | * Object for storing information about the effects of an edit. |
27 | * |
28 | * This object should be constructed by an EditResultBuilder with relevant information filled in |
29 | * during the process of saving the revision by the PageUpdater. You can use it to extract |
30 | * information about whether the edit was a revert and which edits were reverted. |
31 | * |
32 | * @since 1.35 |
33 | * @author Ostrzyciel |
34 | */ |
35 | class EditResult implements JsonSerializable { |
36 | |
37 | // revert methods |
38 | public const REVERT_UNDO = 1; |
39 | public const REVERT_ROLLBACK = 2; |
40 | public const REVERT_MANUAL = 3; |
41 | |
42 | private const SERIALIZATION_FORMAT_VERSION = '1'; |
43 | |
44 | /** @var bool */ |
45 | private $isNew; |
46 | |
47 | /** @var bool|int */ |
48 | private $originalRevisionId; |
49 | |
50 | /** @var int|null */ |
51 | private $revertMethod; |
52 | |
53 | /** @var int|null */ |
54 | private $newestRevertedRevId; |
55 | |
56 | /** @var int|null */ |
57 | private $oldestRevertedRevId; |
58 | |
59 | /** @var bool */ |
60 | private $isExactRevert; |
61 | |
62 | /** @var bool */ |
63 | private $isNullEdit; |
64 | |
65 | /** @var string[] */ |
66 | private $revertTags; |
67 | |
68 | /** |
69 | * @param bool $isNew |
70 | * @param bool|int $originalRevisionId |
71 | * @param int|null $revertMethod |
72 | * @param int|null $oldestReverted |
73 | * @param int|null $newestReverted |
74 | * @param bool $isExactRevert |
75 | * @param bool $isNullEdit |
76 | * @param string[] $revertTags |
77 | * |
78 | * @internal Use EditResultBuilder for constructing EditResults. |
79 | */ |
80 | public function __construct( |
81 | bool $isNew, |
82 | $originalRevisionId, |
83 | ?int $revertMethod, |
84 | ?int $oldestReverted, |
85 | ?int $newestReverted, |
86 | bool $isExactRevert, |
87 | bool $isNullEdit, |
88 | array $revertTags |
89 | ) { |
90 | $this->isNew = $isNew; |
91 | $this->originalRevisionId = $originalRevisionId; |
92 | $this->revertMethod = $revertMethod; |
93 | $this->oldestRevertedRevId = $oldestReverted; |
94 | $this->newestRevertedRevId = $newestReverted; |
95 | $this->isExactRevert = $isExactRevert; |
96 | $this->isNullEdit = $isNullEdit; |
97 | $this->revertTags = $revertTags; |
98 | } |
99 | |
100 | /** |
101 | * Recreate the EditResult object from its array representation. |
102 | * |
103 | * This must ONLY be used for deserializing EditResult objects serialized using |
104 | * EditResult::jsonSerialize(). The structure of the array may change without prior |
105 | * notice. |
106 | * |
107 | * Any changes to the format are guaranteed to be backwards-compatible, so this |
108 | * method will work fine with old serialized EditResults. |
109 | * |
110 | * For constructing EditResult objects from scratch use EditResultBuilder. |
111 | * |
112 | * @see EditResult::jsonSerialize() |
113 | * |
114 | * @param array $a |
115 | * @phpcs:ignore Generic.Files.LineLength |
116 | * @phan-param array{isNew:bool,originalRevisionId:bool|int,revertMethod:int|null,newestRevertedRevId:int|null,oldestRevertedRevId:int|null,isExactRevert:bool,isNullEdit:bool,revertTags:string[],version:string} $a |
117 | * |
118 | * @return EditResult |
119 | * |
120 | * @since 1.36 |
121 | */ |
122 | public static function newFromArray( array $a ) { |
123 | return new self( |
124 | $a['isNew'], |
125 | $a['originalRevisionId'], |
126 | $a['revertMethod'], |
127 | $a['oldestRevertedRevId'], |
128 | $a['newestRevertedRevId'], |
129 | $a['isExactRevert'], |
130 | $a['isNullEdit'], |
131 | $a['revertTags'] |
132 | ); |
133 | } |
134 | |
135 | /** |
136 | * Returns the ID of the most recent revision that was reverted by this edit. |
137 | * The same as getOldestRevertedRevisionId if only a single revision was |
138 | * reverted. Returns null if the edit was not a revert. |
139 | * |
140 | * @see EditResult::isRevert() for information on how a revert is defined |
141 | * |
142 | * @return int|null |
143 | */ |
144 | public function getNewestRevertedRevisionId(): ?int { |
145 | return $this->newestRevertedRevId; |
146 | } |
147 | |
148 | /** |
149 | * Returns the ID of the oldest revision that was reverted by this edit. |
150 | * The same as getOldestRevertedRevisionId if only a single revision was |
151 | * reverted. Returns null if the edit was not a revert. |
152 | * |
153 | * @see EditResult::isRevert() for information on how a revert is defined |
154 | * |
155 | * @return int|null |
156 | */ |
157 | public function getOldestRevertedRevisionId(): ?int { |
158 | return $this->oldestRevertedRevId; |
159 | } |
160 | |
161 | /** |
162 | * If the edit was an undo, returns the oldest revision that was undone. |
163 | * Method kept for compatibility reasons. |
164 | * |
165 | * @return int |
166 | */ |
167 | public function getUndidRevId(): int { |
168 | if ( $this->getRevertMethod() !== self::REVERT_UNDO ) { |
169 | return 0; |
170 | } |
171 | return $this->getOldestRevertedRevisionId() ?? 0; |
172 | } |
173 | |
174 | /** |
175 | * Returns the ID of an earlier revision that is being repeated or restored. |
176 | * |
177 | * The original revision's content should match the new revision exactly. |
178 | * |
179 | * @return bool|int The original revision id, or false if no earlier revision is known to be |
180 | * repeated or restored. |
181 | * The old PageUpdater::getOriginalRevisionId() returned false in such cases. This value would |
182 | * be then passed on to extensions through hooks, so it may be wise to keep compatibility with |
183 | * the old behavior. |
184 | */ |
185 | public function getOriginalRevisionId() { |
186 | return $this->originalRevisionId; |
187 | } |
188 | |
189 | /** |
190 | * Whether the edit created a new page |
191 | * |
192 | * @return bool |
193 | */ |
194 | public function isNew(): bool { |
195 | return $this->isNew; |
196 | } |
197 | |
198 | /** |
199 | * Whether the edit was a revert, not necessarily exact. |
200 | * |
201 | * An edit is considered a revert if it either: |
202 | * - Restores the page to an exact previous state (rollbacks, manual reverts and some undos). |
203 | * E.g. for edits A B C D, edits C and D are reverted. |
204 | * - Undoes some edits made previously, not necessarily restoring the page to an exact |
205 | * previous state (undo). It is guaranteed that the revert was a "clean" result of a |
206 | * three-way merge and no additional changes were made by the reverting user. |
207 | * E.g. for edits A B C D, edits B and C are reverted. |
208 | * |
209 | * To check whether the edit was an exact revert, please use the isExactRevert() method. |
210 | * The getRevertMethod() will provide additional information about which kind of revert |
211 | * was made. |
212 | * |
213 | * @return bool |
214 | */ |
215 | public function isRevert(): bool { |
216 | return !$this->isNew() && $this->getOldestRevertedRevisionId(); |
217 | } |
218 | |
219 | /** |
220 | * Returns the revert method that was used to perform the edit, if any changes were reverted. |
221 | * Returns null if the edit was not a revert. |
222 | * |
223 | * Possible values: REVERT_UNDO, REVERT_ROLLBACK, REVERT_MANUAL |
224 | * |
225 | * @see EditResult::isRevert() |
226 | * |
227 | * @return int|null |
228 | */ |
229 | public function getRevertMethod(): ?int { |
230 | return $this->revertMethod; |
231 | } |
232 | |
233 | /** |
234 | * Whether the edit was an exact revert, |
235 | * i.e. the contents of the revert revision and restored revision match |
236 | * |
237 | * @return bool |
238 | */ |
239 | public function isExactRevert(): bool { |
240 | return $this->isExactRevert; |
241 | } |
242 | |
243 | /** |
244 | * An edit is a null edit if the original revision is equal to the parent revision, |
245 | * i.e. no changes were made. |
246 | * |
247 | * @return bool |
248 | */ |
249 | public function isNullEdit(): bool { |
250 | return $this->isNullEdit; |
251 | } |
252 | |
253 | /** |
254 | * Returns an array of revert-related tags that were applied automatically to this edit. |
255 | * |
256 | * @return string[] |
257 | */ |
258 | public function getRevertTags(): array { |
259 | return $this->revertTags; |
260 | } |
261 | |
262 | /** |
263 | * Returns an array representing the EditResult object. |
264 | * |
265 | * @see EditResult::newFromArray() |
266 | * |
267 | * @return array |
268 | * @phpcs:ignore Generic.Files.LineLength |
269 | * @phan-return array{isNew:bool,originalRevisionId:bool|int,revertMethod:int|null,newestRevertedRevId:int|null,oldestRevertedRevId:int|null,isExactRevert:bool,isNullEdit:bool,revertTags:string[],version:string} |
270 | * |
271 | * @since 1.36 |
272 | */ |
273 | public function jsonSerialize(): array { |
274 | return [ |
275 | 'isNew' => $this->isNew, |
276 | 'originalRevisionId' => $this->originalRevisionId, |
277 | 'revertMethod' => $this->revertMethod, |
278 | 'newestRevertedRevId' => $this->newestRevertedRevId, |
279 | 'oldestRevertedRevId' => $this->oldestRevertedRevId, |
280 | 'isExactRevert' => $this->isExactRevert, |
281 | 'isNullEdit' => $this->isNullEdit, |
282 | 'revertTags' => $this->revertTags, |
283 | 'version' => self::SERIALIZATION_FORMAT_VERSION |
284 | ]; |
285 | } |
286 | } |