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