Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
87.50% covered (warning)
87.50%
28 / 32
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
AbstractUndoAction
87.50% covered (warning)
87.50%
28 / 32
50.00% covered (danger)
50.00%
2 / 4
8.12
0.00% covered (danger)
0.00%
0 / 1
 getRestriction
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDiffFromRequest
75.00% covered (warning)
75.00%
9 / 12
0.00% covered (danger)
0.00%
0 / 1
4.25
 tryPatching
90.00% covered (success)
90.00%
9 / 10
0.00% covered (danger)
0.00%
0 / 1
2.00
 showUndoErrorPage
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare( strict_types = 1 );
4
5namespace EntitySchema\MediaWiki\Actions;
6
7use Diff\DiffOp\Diff\Diff;
8use DomainException;
9use EntitySchema\MediaWiki\Content\EntitySchemaContent;
10use EntitySchema\MediaWiki\UndoHandler;
11use MediaWiki\MediaWikiServices;
12use MediaWiki\Request\WebRequest;
13use MediaWiki\Revision\SlotRecord;
14use MediaWiki\Status\Status;
15use ViewAction;
16
17/**
18 * @license GPL-2.0-or-later
19 */
20abstract 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}