Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 84
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialComparePages
0.00% covered (danger)
0.00%
0 / 83
0.00% covered (danger)
0.00%
0 / 6
210
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 54
0.00% covered (danger)
0.00%
0 / 1
6
 showDiff
0.00% covered (danger)
0.00%
0 / 16
0.00% covered (danger)
0.00%
0 / 1
12
 revOrTitle
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 checkExistingRevision
0.00% covered (danger)
0.00%
0 / 6
0.00% covered (danger)
0.00%
0 / 1
20
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Copyright © 2010 Derk-Jan Hartman <hartman@videolan.org>
4 *
5 * @license GPL-2.0-or-later
6 * @file
7 */
8
9namespace MediaWiki\Specials;
10
11use MediaWiki\Content\IContentHandlerFactory;
12use MediaWiki\Diff\DifferenceEngine;
13use MediaWiki\HTMLForm\HTMLForm;
14use MediaWiki\Revision\RevisionLookup;
15use MediaWiki\Revision\RevisionRecord;
16use MediaWiki\Revision\SlotRecord;
17use MediaWiki\SpecialPage\SpecialPage;
18use MediaWiki\Title\Title;
19
20/**
21 * Implements Special:ComparePages
22 *
23 * @ingroup SpecialPage
24 */
25class SpecialComparePages extends SpecialPage {
26
27    /** @var DifferenceEngine */
28    private $differenceEngine;
29
30    public function __construct(
31        private readonly RevisionLookup $revisionLookup,
32        private readonly IContentHandlerFactory $contentHandlerFactory
33    ) {
34        parent::__construct( 'ComparePages' );
35    }
36
37    /**
38     * Show a form for filtering namespace and username
39     *
40     * @param string|null $par
41     */
42    public function execute( $par ) {
43        $this->setHeaders();
44        $this->outputHeader();
45        $this->getOutput()->addModuleStyles( 'mediawiki.special' );
46        $this->addHelpLink( 'Help:Diff' );
47
48        $form = HTMLForm::factory( 'ooui', [
49            'Page1' => [
50                'type' => 'title',
51                'exists' => true,
52                'name' => 'page1',
53                'label-message' => 'compare-page1',
54                'size' => '40',
55                'section' => 'page1',
56                'required' => false,
57            ],
58            'Revision1' => [
59                'type' => 'int',
60                'name' => 'rev1',
61                'label-message' => 'compare-rev1',
62                'size' => '8',
63                'section' => 'page1',
64                'validation-callback' => $this->checkExistingRevision( ... ),
65            ],
66            'Page2' => [
67                'type' => 'title',
68                'name' => 'page2',
69                'exists' => true,
70                'label-message' => 'compare-page2',
71                'size' => '40',
72                'section' => 'page2',
73                'required' => false,
74            ],
75            'Revision2' => [
76                'type' => 'int',
77                'name' => 'rev2',
78                'label-message' => 'compare-rev2',
79                'size' => '8',
80                'section' => 'page2',
81                'validation-callback' => $this->checkExistingRevision( ... ),
82            ],
83            'Action' => [
84                'type' => 'hidden',
85                'name' => 'action',
86            ],
87            'Unhide' => [
88                'type' => 'hidden',
89                'name' => 'unhide',
90            ],
91        ], $this->getContext(), 'compare' );
92
93        $form->setMethod( 'get' )
94            ->setSubmitTextMsg( 'compare-submit' )
95            ->setSubmitCallback( $this->showDiff( ... ) )
96            ->show();
97
98        if ( $this->differenceEngine ) {
99            $this->differenceEngine->showDiffPage( true );
100        }
101    }
102
103    /**
104     * @param array $data
105     * @param HTMLForm $form
106     */
107    private function showDiff( $data, HTMLForm $form ) {
108        $rev1 = $this->revOrTitle( $data['Revision1'], $data['Page1'] );
109        $rev2 = $this->revOrTitle( $data['Revision2'], $data['Page2'] );
110
111        if ( $rev1 && $rev2 ) {
112            // Revision IDs either passed the existence check or were fetched from existing titles.
113            $revisionRecord = $this->revisionLookup->getRevisionById( $rev1 );
114            $contentModel = $revisionRecord->getSlot(
115                SlotRecord::MAIN,
116                RevisionRecord::RAW
117            )->getModel();
118            $contentHandler = $this->contentHandlerFactory->getContentHandler( $contentModel );
119            $this->differenceEngine = $contentHandler->createDifferenceEngine( $form->getContext(),
120                $rev1,
121                $rev2,
122                0, // rcid
123                ( $data['Action'] == 'purge' ),
124                ( $data['Unhide'] == '1' )
125            );
126        }
127    }
128
129    private function revOrTitle( ?string $revision, ?string $title ): ?int {
130        if ( $revision ) {
131            return (int)$revision;
132        } elseif ( $title ) {
133            return Title::newFromText( $title )->getLatestRevID();
134        }
135
136        return null;
137    }
138
139    /**
140     * @param string|null $value
141     * @param array $alldata
142     * @return string|bool
143     */
144    private function checkExistingRevision( $value, $alldata ) {
145        if ( $value === '' || $value === null ) {
146            return true;
147        }
148        $revisionRecord = $this->revisionLookup->getRevisionById( (int)$value );
149        if ( $revisionRecord === null ) {
150            return $this->msg( 'compare-revision-not-exists' )->parseAsBlock();
151        }
152
153        return true;
154    }
155
156    /** @inheritDoc */
157    protected function getGroupName() {
158        return 'pagetools';
159    }
160}
161
162/** @deprecated class alias since 1.41 */
163class_alias( SpecialComparePages::class, 'SpecialComparePages' );