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 | public function getUndidRevId(): int { |
166 | if ( $this->getRevertMethod() !== self::REVERT_UNDO ) { |
167 | return 0; |
168 | } |
169 | return $this->getOldestRevertedRevisionId() ?? 0; |
170 | } |
171 | |
172 | /** |
173 | * Returns the ID of an earlier revision that is being repeated or restored. |
174 | * |
175 | * The original revision's content should match the new revision exactly. |
176 | * |
177 | * @return bool|int The original revision id, or false if no earlier revision is known to be |
178 | * repeated or restored. |
179 | * The old PageUpdater::getOriginalRevisionId() returned false in such cases. This value would |
180 | * be then passed on to extensions through hooks, so it may be wise to keep compatibility with |
181 | * the old behavior. |
182 | */ |
183 | public function getOriginalRevisionId() { |
184 | return $this->originalRevisionId; |
185 | } |
186 | |
187 | /** |
188 | * Whether the edit created a new page |
189 | */ |
190 | public function isNew(): bool { |
191 | return $this->isNew; |
192 | } |
193 | |
194 | /** |
195 | * Whether the edit was a revert, not necessarily exact. |
196 | * |
197 | * An edit is considered a revert if it either: |
198 | * - Restores the page to an exact previous state (rollbacks, manual reverts and some undos). |
199 | * E.g. for edits A B C D, edits C and D are reverted. |
200 | * - Undoes some edits made previously, not necessarily restoring the page to an exact |
201 | * previous state (undo). It is guaranteed that the revert was a "clean" result of a |
202 | * three-way merge and no additional changes were made by the reverting user. |
203 | * E.g. for edits A B C D, edits B and C are reverted. |
204 | * |
205 | * To check whether the edit was an exact revert, please use the isExactRevert() method. |
206 | * The getRevertMethod() will provide additional information about which kind of revert |
207 | * was made. |
208 | */ |
209 | public function isRevert(): bool { |
210 | return !$this->isNew() && $this->getOldestRevertedRevisionId(); |
211 | } |
212 | |
213 | /** |
214 | * Returns the revert method that was used to perform the edit, if any changes were reverted. |
215 | * Returns null if the edit was not a revert. |
216 | * |
217 | * Possible values: REVERT_UNDO, REVERT_ROLLBACK, REVERT_MANUAL |
218 | * |
219 | * @see EditResult::isRevert() |
220 | * |
221 | * @return int|null |
222 | */ |
223 | public function getRevertMethod(): ?int { |
224 | return $this->revertMethod; |
225 | } |
226 | |
227 | /** |
228 | * Whether the edit was an exact revert, |
229 | * i.e. the contents of the revert revision and restored revision match |
230 | */ |
231 | public function isExactRevert(): bool { |
232 | return $this->isExactRevert; |
233 | } |
234 | |
235 | /** |
236 | * An edit is a null edit if the original revision is equal to the parent revision, |
237 | * i.e. no changes were made. |
238 | */ |
239 | public function isNullEdit(): bool { |
240 | return $this->isNullEdit; |
241 | } |
242 | |
243 | /** |
244 | * Returns an array of revert-related tags that were applied automatically to this edit. |
245 | * |
246 | * @return string[] |
247 | */ |
248 | public function getRevertTags(): array { |
249 | return $this->revertTags; |
250 | } |
251 | |
252 | /** |
253 | * Returns an array representing the EditResult object. |
254 | * |
255 | * @see EditResult::newFromArray() |
256 | * |
257 | * @return array |
258 | * @phpcs:ignore Generic.Files.LineLength |
259 | * @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} |
260 | * |
261 | * @since 1.36 |
262 | */ |
263 | public function jsonSerialize(): array { |
264 | return [ |
265 | 'isNew' => $this->isNew, |
266 | 'originalRevisionId' => $this->originalRevisionId, |
267 | 'revertMethod' => $this->revertMethod, |
268 | 'newestRevertedRevId' => $this->newestRevertedRevId, |
269 | 'oldestRevertedRevId' => $this->oldestRevertedRevId, |
270 | 'isExactRevert' => $this->isExactRevert, |
271 | 'isNullEdit' => $this->isNullEdit, |
272 | 'revertTags' => $this->revertTags, |
273 | 'version' => self::SERIALIZATION_FORMAT_VERSION |
274 | ]; |
275 | } |
276 | } |