Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 66
0.00% covered (danger)
0.00%
0 / 9
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiMergeHistory
0.00% covered (danger)
0.00%
0 / 65
0.00% covered (danger)
0.00%
0 / 9
420
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 execute
0.00% covered (danger)
0.00%
0 / 36
0.00% covered (danger)
0.00%
0 / 1
156
 merge
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 mustBePosted
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isWriteMode
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getAllowedParams
0.00% covered (danger)
0.00%
0 / 13
0.00% covered (danger)
0.00%
0 / 1
2
 needsToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getExamplesMessages
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 getHelpUrls
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Copyright © 2015 Geoffrey Mon <geofbot@gmail.com>
4 *
5 * @license GPL-2.0-or-later
6 * @file
7 */
8
9namespace MediaWiki\Api;
10
11use MediaWiki\Page\MergeHistoryFactory;
12use MediaWiki\Page\PageIdentity;
13use MediaWiki\Status\Status;
14use MediaWiki\Title\Title;
15use Wikimedia\ParamValidator\ParamValidator;
16
17/**
18 * API Module to merge page histories
19 * @ingroup API
20 */
21class ApiMergeHistory extends ApiBase {
22
23    private MergeHistoryFactory $mergeHistoryFactory;
24
25    public function __construct(
26        ApiMain $mainModule,
27        string $moduleName,
28        MergeHistoryFactory $mergeHistoryFactory
29    ) {
30        parent::__construct( $mainModule, $moduleName );
31        $this->mergeHistoryFactory = $mergeHistoryFactory;
32    }
33
34    public function execute() {
35        $this->useTransactionalTimeLimit();
36
37        $params = $this->extractRequestParams();
38
39        $this->requireOnlyOneParameter( $params, 'from', 'fromid' );
40        $this->requireOnlyOneParameter( $params, 'to', 'toid' );
41
42        // Get page objects (nonexistent pages get caught in MergeHistory::isValidMerge())
43        if ( isset( $params['from'] ) ) {
44            $fromTitle = Title::newFromText( $params['from'] );
45            if ( !$fromTitle || $fromTitle->isExternal() ) {
46                $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['from'] ) ] );
47            }
48        } elseif ( isset( $params['fromid'] ) ) {
49            $fromTitle = Title::newFromID( $params['fromid'] );
50            if ( !$fromTitle ) {
51                $this->dieWithError( [ 'apierror-nosuchpageid', $params['fromid'] ] );
52            }
53        } else {
54            self::dieDebug( __METHOD__, 'unknown from parameter' );
55        }
56
57        if ( isset( $params['to'] ) ) {
58            $toTitle = Title::newFromText( $params['to'] );
59            if ( !$toTitle || $toTitle->isExternal() ) {
60                $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['to'] ) ] );
61            }
62        } elseif ( isset( $params['toid'] ) ) {
63            $toTitle = Title::newFromID( $params['toid'] );
64            if ( !$toTitle ) {
65                $this->dieWithError( [ 'apierror-nosuchpageid', $params['toid'] ] );
66            }
67        } else {
68            self::dieDebug( __METHOD__, 'unknown to parameter' );
69        }
70
71        $reason = $params['reason'];
72        $timestamp = $params['timestamp'] ?? '';
73        $startTimestamp = $params['starttimestamp'] ?? '';
74
75        // Merge!
76        $status = $this->merge( $fromTitle, $toTitle, $timestamp, $reason, $startTimestamp );
77        if ( !$status->isOK() ) {
78            $this->dieStatus( $status );
79        }
80
81        $r = [
82            'from' => $fromTitle->getPrefixedText(),
83            'to' => $toTitle->getPrefixedText(),
84            'timestamp' => $params['timestamp'],
85            'reason' => $params['reason']
86        ];
87        $result = $this->getResult();
88
89        $result->addValue( null, $this->getModuleName(), $r );
90    }
91
92    /**
93     * @param PageIdentity $from
94     * @param PageIdentity $to
95     * @param string $timestamp
96     * @param string $reason
97     * @param string $startTimestamp
98     * @return Status
99     */
100    protected function merge( PageIdentity $from, PageIdentity $to, $timestamp, $reason, $startTimestamp ) {
101        $mh = $this->mergeHistoryFactory->newMergeHistory( $from, $to, $timestamp, $startTimestamp );
102
103        return $mh->merge( $this->getAuthority(), $reason );
104    }
105
106    /** @inheritDoc */
107    public function mustBePosted() {
108        return true;
109    }
110
111    /** @inheritDoc */
112    public function isWriteMode() {
113        return true;
114    }
115
116    /** @inheritDoc */
117    public function getAllowedParams() {
118        return [
119            'from' => null,
120            'fromid' => [
121                ParamValidator::PARAM_TYPE => 'integer'
122            ],
123            'to' => null,
124            'toid' => [
125                ParamValidator::PARAM_TYPE => 'integer'
126            ],
127            // This can either be a timestamp or a timestamp-with-ID pair; don't reject the latter in validation
128            'timestamp' => null,
129            'reason' => '',
130            'starttimestamp' => null
131        ];
132    }
133
134    /** @inheritDoc */
135    public function needsToken() {
136        return 'csrf';
137    }
138
139    /** @inheritDoc */
140    protected function getExamplesMessages() {
141        return [
142            'action=mergehistory&from=Oldpage&to=Newpage&token=123ABC&' .
143            'reason=Reason'
144            => 'apihelp-mergehistory-example-merge',
145            'action=mergehistory&from=Oldpage&to=Newpage&token=123ABC&' .
146            'reason=Reason&timestamp=2015-12-31T04%3A37%3A41Z' // TODO
147            => 'apihelp-mergehistory-example-merge-timestamp',
148        ];
149    }
150
151    /** @inheritDoc */
152    public function getHelpUrls() {
153        return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Mergehistory';
154    }
155}
156
157/** @deprecated class alias since 1.43 */
158class_alias( ApiMergeHistory::class, 'ApiMergeHistory' );