Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
90.00% covered (success)
90.00%
45 / 50
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
RestoreViewAction
90.00% covered (success)
90.00%
45 / 50
50.00% covered (danger)
50.00%
2 / 4
7.05
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 show
63.64% covered (warning)
63.64%
7 / 11
0.00% covered (danger)
0.00%
0 / 1
3.43
 showRestorePreview
100.00% covered (success)
100.00%
24 / 24
100.00% covered (success)
100.00%
1 / 1
1
 getDiffFromRevision
92.31% covered (success)
92.31%
12 / 13
0.00% covered (danger)
0.00%
0 / 1
2.00
1<?php
2
3declare( strict_types = 1 );
4
5namespace EntitySchema\MediaWiki\Actions;
6
7use Article;
8use Diff\DiffOp\Diff\Diff;
9use EntitySchema\MediaWiki\Content\EntitySchemaContent;
10use EntitySchema\MediaWiki\Content\EntitySchemaSlotDiffRenderer;
11use EntitySchema\Presentation\ConfirmationFormRenderer;
12use EntitySchema\Presentation\DiffRenderer;
13use EntitySchema\Services\Converter\EntitySchemaConverter;
14use EntitySchema\Services\Diff\EntitySchemaDiffer;
15use IContextSource;
16use MediaWiki\MediaWikiServices;
17use MediaWiki\Revision\RevisionRecord;
18use MediaWiki\Revision\SlotRecord;
19use MediaWiki\Status\Status;
20
21/**
22 * @license GPL-2.0-or-later
23 */
24final class RestoreViewAction extends AbstractRestoreAction {
25
26    private EntitySchemaSlotDiffRenderer $slotDiffRenderer;
27
28    public function __construct(
29        Article $article,
30        IContextSource $context,
31        EntitySchemaSlotDiffRenderer $slotDiffRenderer
32    ) {
33        parent::__construct( $article, $context );
34        $this->slotDiffRenderer = $slotDiffRenderer;
35    }
36
37    public function show(): void {
38        $this->checkPermissions();
39
40        $req = $this->getContext()->getRequest();
41        $revStatus = $this->getRevisionFromRequest( $req );
42        if ( !$revStatus->isOK() ) {
43            $this->showRestoreErrorPage( $revStatus );
44            return;
45        }
46
47        $diffStatus = $this->getDiffFromRevision( $revStatus->getValue() );
48        if ( !$diffStatus->isOK() ) {
49            $this->showRestoreErrorPage( $diffStatus );
50            return;
51        }
52
53        $this->showRestorePreview( $diffStatus->getValue(), $req->getInt( 'restore' ) );
54    }
55
56    private function showRestorePreview( Diff $diff, int $restoredRevID ): void {
57        $this->getOutput()->enableOOUI();
58        $this->getOutput()->setPageTitle(
59            $this->msg(
60                'entityschema-restore-heading',
61                $this->getTitle()->getTitleValue()->getText()
62            )
63        );
64
65        $diffRenderer = new DiffRenderer( $this, $this->slotDiffRenderer );
66        $diffHTML = $diffRenderer->renderSchemaDiffTable(
67            $this->slotDiffRenderer->renderSchemaDiffRows( $diff ),
68            $this->msg( 'currentrev' )
69        );
70
71        $this->getOutput()->addHTML( $diffHTML );
72        $this->getOutput()->addModuleStyles( 'mediawiki.diff.styles' );
73
74        $confFormRenderer = new ConfirmationFormRenderer( $this );
75        $confFormHTML = $confFormRenderer->showUndoRestoreConfirmationForm(
76            [
77                'restore' => $restoredRevID,
78            ],
79            'restore',
80            $this->getTitle(),
81            $this->getUser()
82        );
83
84        $this->getOutput()->addHTML( $confFormHTML );
85    }
86
87    private function getDiffFromRevision( RevisionRecord $revToRestore ): Status {
88
89        /** @var EntitySchemaContent $contentToRestore */
90        $contentToRestore = $revToRestore->getContent( SlotRecord::MAIN );
91
92        /** @var EntitySchemaContent $baseContent */
93        $baseContent = MediaWikiServices::getInstance()->getRevisionStore()
94            ->getRevisionById( $this->getTitle()->getLatestRevID() )
95            ->getContent( SlotRecord::MAIN );
96
97        $differ = new EntitySchemaDiffer();
98        $converter = new EntitySchemaConverter();
99        $diff = $differ->diffSchemas(
100        // @phan-suppress-next-line PhanUndeclaredMethod
101            $converter->getFullArraySchemaData( $baseContent->getText() ),
102            // @phan-suppress-next-line PhanUndeclaredMethod
103            $converter->getFullArraySchemaData( $contentToRestore->getText() )
104        );
105
106        if ( $diff->isEmpty() ) {
107            return Status::newFatal( 'entityschema-restore-empty' );
108        }
109
110        return Status::newGood( $diff );
111    }
112
113}