Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
87.50% |
28 / 32 |
|
50.00% |
2 / 4 |
CRAP | |
0.00% |
0 / 1 |
AbstractUndoAction | |
87.50% |
28 / 32 |
|
50.00% |
2 / 4 |
8.12 | |
0.00% |
0 / 1 |
getRestriction | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDiffFromRequest | |
75.00% |
9 / 12 |
|
0.00% |
0 / 1 |
4.25 | |||
tryPatching | |
90.00% |
9 / 10 |
|
0.00% |
0 / 1 |
2.00 | |||
showUndoErrorPage | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | |
3 | declare( strict_types = 1 ); |
4 | |
5 | namespace EntitySchema\MediaWiki\Actions; |
6 | |
7 | use Diff\DiffOp\Diff\Diff; |
8 | use DomainException; |
9 | use EntitySchema\MediaWiki\Content\EntitySchemaContent; |
10 | use EntitySchema\MediaWiki\UndoHandler; |
11 | use MediaWiki\MediaWikiServices; |
12 | use MediaWiki\Request\WebRequest; |
13 | use MediaWiki\Revision\SlotRecord; |
14 | use MediaWiki\Status\Status; |
15 | use ViewAction; |
16 | |
17 | /** |
18 | * @license GPL-2.0-or-later |
19 | */ |
20 | abstract class AbstractUndoAction extends ViewAction { |
21 | |
22 | public function getRestriction(): string { |
23 | return $this->getName(); |
24 | } |
25 | |
26 | protected function getDiffFromRequest( WebRequest $req ): Status { |
27 | |
28 | $revStore = MediaWikiServices::getInstance()->getRevisionStore(); |
29 | |
30 | $newerRevision = $revStore->getRevisionById( $req->getInt( 'undo' ) ); |
31 | $olderRevision = $revStore->getRevisionById( $req->getInt( 'undoafter' ) ); |
32 | |
33 | if ( $newerRevision === null || $olderRevision === null ) { |
34 | return Status::newFatal( 'entityschema-undo-bad-revisions' ); |
35 | } |
36 | |
37 | /** @var EntitySchemaContent $undoFromContent */ |
38 | $undoFromContent = $newerRevision->getContent( SlotRecord::MAIN ); |
39 | '@phan-var EntitySchemaContent $undoFromContent'; |
40 | /** @var EntitySchemaContent $undoToContent */ |
41 | $undoToContent = $olderRevision->getContent( SlotRecord::MAIN ); |
42 | '@phan-var EntitySchemaContent $undoToContent'; |
43 | $undoHandler = new UndoHandler(); |
44 | try { |
45 | $undoHandler->validateContentIds( $undoFromContent, $undoToContent ); |
46 | } catch ( DomainException $e ) { |
47 | return Status::newFatal( 'entityschema-error-inconsistent-id' ); |
48 | } |
49 | |
50 | return $undoHandler->getDiffFromContents( $undoFromContent, $undoToContent ); |
51 | } |
52 | |
53 | /** |
54 | * Try applying the diff to the latest revision of this page. |
55 | * |
56 | * @param Diff $diff |
57 | * |
58 | * @return Status contains array of the patched schema data and the revision that was patched |
59 | */ |
60 | protected function tryPatching( Diff $diff ): Status { |
61 | $revStore = MediaWikiServices::getInstance()->getRevisionStore(); |
62 | $baseRevId = $this->getTitle()->getLatestRevID(); |
63 | /** @var EntitySchemaContent $baseContent */ |
64 | $baseContent = $revStore |
65 | ->getRevisionById( $baseRevId ) |
66 | ->getContent( SlotRecord::MAIN ); |
67 | '@phan-var EntitySchemaContent $baseContent'; |
68 | $undoHandler = new UndoHandler(); |
69 | $status = $undoHandler->tryPatching( $diff, $baseContent ); |
70 | if ( $status->isGood() ) { |
71 | return Status::newGood( [ $status->getValue(), $baseRevId ] ); |
72 | } |
73 | |
74 | return $status; |
75 | } |
76 | |
77 | /** |
78 | * Output an error page showing the given status |
79 | * |
80 | * @param Status $status The status to report. |
81 | */ |
82 | protected function showUndoErrorPage( Status $status ): void { |
83 | $this->getOutput()->prepareErrorPage(); |
84 | $this->getOutput()->setPageTitleMsg( |
85 | $this->msg( 'entityschema-undo-heading-failed' ) |
86 | ); |
87 | $this->getOutput()->setHTMLTitle( |
88 | $this->msg( 'errorpagetitle' ) |
89 | ); |
90 | |
91 | $this->getOutput()->addHTML( $status->getMessage()->parse() ); |
92 | |
93 | $this->getOutput()->returnToMain(); |
94 | } |
95 | |
96 | } |