Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
89.39% covered (warning)
89.39%
59 / 66
57.14% covered (warning)
57.14%
4 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
RestoreSubmitAction
89.39% covered (warning)
89.39%
59 / 66
57.14% covered (warning)
57.14%
4 / 7
14.23
0.00% covered (danger)
0.00%
0 / 1
 getName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 show
77.78% covered (warning)
77.78%
14 / 18
0.00% covered (danger)
0.00%
0 / 1
5.27
 checkMethod
66.67% covered (warning)
66.67%
2 / 3
0.00% covered (danger)
0.00%
0 / 1
2.15
 checkCurrentRevison
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 restore
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
1
 storeRestoredSchema
84.62% covered (warning)
84.62%
11 / 13
0.00% covered (danger)
0.00%
0 / 1
2.01
 createSummaryMessageForRestore
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3declare( strict_types = 1 );
4
5namespace EntitySchema\MediaWiki\Actions;
6
7use EntitySchema\DataAccess\MediaWikiRevisionEntitySchemaUpdater;
8use EntitySchema\Domain\Model\EntitySchemaId;
9use EntitySchema\MediaWiki\Content\EntitySchemaContent;
10use EntitySchema\Services\Converter\EntitySchemaConverter;
11use EntitySchema\Services\Converter\PersistenceEntitySchemaData;
12use MediaWiki\CommentStore\CommentStoreComment;
13use MediaWiki\Revision\RevisionRecord;
14use MediaWiki\Revision\SlotRecord;
15use MediaWiki\Status\Status;
16use RuntimeException;
17
18/**
19 * @license GPL-2.0-or-later
20 */
21final class RestoreSubmitAction extends AbstractRestoreAction {
22
23    public function getName(): string {
24        return 'submit';
25    }
26
27    public function show(): void {
28        $checkMethodStatus = $this->checkMethod();
29        if ( !$checkMethodStatus->isOK() ) {
30            $this->showRestoreErrorPage( Status::newFatal( $checkMethodStatus ) );
31        }
32
33        $this->checkPermissions();
34
35        $currentRevStatus = $this->checkCurrentRevison();
36        if ( !$currentRevStatus->isOK() ) {
37            $this->showRestoreErrorPage( $currentRevStatus );
38            return;
39        }
40
41        $revStatus = $this->getRevisionFromRequest( $this->getContext()->getRequest() );
42        if ( !$revStatus->isOK() ) {
43            $this->showRestoreErrorPage( $revStatus );
44            return;
45        }
46
47        $restoreStatus = $this->restore( $revStatus->getValue() );
48        if ( !$restoreStatus->isOK() ) {
49            $this->showRestoreErrorPage( $restoreStatus );
50        }
51
52        $this->getOutput()->redirect(
53            $this->getTitle()->getFullURL()
54        );
55    }
56
57    private function checkMethod(): Status {
58        if ( !$this->getContext()->getRequest()->wasPosted() ) {
59            return Status::newFatal( 'entityschema-error-not-post' );
60        }
61
62        return Status::newGood();
63    }
64
65    private function checkCurrentRevison(): Status {
66        $req = $this->getContext()->getRequest();
67
68        if ( $this->getTitle()->getLatestRevID() !== (int)$req->getText( 'wpBaseRev' ) ) {
69            return Status::newFatal( $this->msg( 'entityschema-restore-changed' ) );
70        }
71
72        return Status::newGood();
73    }
74
75    private function restore( RevisionRecord $revToRestore ): Status {
76        /** @var EntitySchemaContent $contentToRestore */
77        $contentToRestore = $revToRestore->getContent( SlotRecord::MAIN );
78
79        $converter = new EntitySchemaConverter();
80
81        $summary = $this->createSummaryMessageForRestore(
82            $this->getContext()->getRequest()->getText( 'wpSummary' ),
83            $revToRestore
84        );
85
86        return $this->storeRestoredSchema(
87            $converter->getPersistenceSchemaData(
88            // @phan-suppress-next-line PhanUndeclaredMethod
89                $contentToRestore->getText()
90            ),
91            $this->getContext()->getRequest()->getInt( 'wpBaseRev' ),
92            $summary
93        );
94    }
95
96    private function storeRestoredSchema(
97        PersistenceEntitySchemaData $persistenceSchemaData,
98        int $baseRevId,
99        CommentStoreComment $summary
100    ): Status {
101
102        $schemaUpdater = MediaWikiRevisionEntitySchemaUpdater::newFromContext( $this->getContext() );
103
104        try {
105            $schemaUpdater->overwriteWholeSchema(
106                new EntitySchemaId( $this->getTitle()->getTitleValue()->getText() ),
107                $persistenceSchemaData->labels,
108                $persistenceSchemaData->descriptions,
109                $persistenceSchemaData->aliases,
110                $persistenceSchemaData->schemaText,
111                $baseRevId,
112                $summary
113            );
114        } catch ( RuntimeException $e ) {
115            return Status::newFatal( 'entityschema-error-saving-failed', $e->getMessage() );
116        }
117
118        return Status::newGood();
119    }
120
121    private function createSummaryMessageForRestore(
122        string $userSummary,
123        RevisionRecord $revToBeRestored
124    ): CommentStoreComment {
125        $revId = $revToBeRestored->getId();
126        $userName = $revToBeRestored->getUser()->getName();
127        $autoComment = MediaWikiRevisionEntitySchemaUpdater::AUTOCOMMENT_RESTORE
128            . ':' . $revId
129            . ':' . $userName;
130        return CommentStoreComment::newUnsavedComment(
131            '/* ' . $autoComment . ' */' . $userSummary,
132            [
133                'key' => MediaWikiRevisionEntitySchemaUpdater::AUTOCOMMENT_RESTORE,
134                'revId' => $revId,
135                'userName' => $userName,
136                'summary' => $userSummary,
137            ]
138        );
139    }
140
141}