Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
88.10% covered (warning)
88.10%
37 / 42
57.14% covered (warning)
57.14%
4 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiSanitizeMapData
88.10% covered (warning)
88.10%
37 / 42
57.14% covered (warning)
57.14%
4 / 7
9.14
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
 execute
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 sanitizeJson
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
2
 getAllowedParams
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
1
 mustBePosted
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 / 3
0.00% covered (danger)
0.00%
0 / 1
2
 isInternal
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 *
4 * @license MIT
5 * @file
6 *
7 * @author Yuri Astrakhan
8 * @author Max Semenik
9 */
10
11namespace Kartographer\Api;
12
13use ApiBase;
14use ApiMain;
15use FormatJson;
16use Kartographer\MediaWikiWikitextParser;
17use Kartographer\SimpleStyleParser;
18use MediaWiki\Status\Status;
19use MediaWiki\Title\Title;
20use Parser;
21use ParserFactory;
22use ParserOptions;
23use Wikimedia\ParamValidator\ParamValidator;
24
25/**
26 * This class implements action=sanitize-mapdata API, validating and sanitizing user-entered
27 * GeoJSON.
28 *
29 * @license MIT
30 */
31class ApiSanitizeMapData extends ApiBase {
32
33    private ParserFactory $parserFactory;
34
35    /**
36     * @param ApiMain $main
37     * @param string $action
38     * @param ParserFactory $parserFactory
39     */
40    public function __construct(
41        ApiMain $main,
42        $action,
43        ParserFactory $parserFactory
44    ) {
45        parent::__construct( $main, $action );
46        $this->parserFactory = $parserFactory;
47    }
48
49    /** @inheritDoc */
50    public function execute() {
51        $params = $this->extractRequestParams();
52
53        $title = Title::newFromText( $params['title'] );
54
55        if ( !$title ) {
56            $this->dieWithError( [ 'apierror-invalidtitle', wfEscapeWikiText( $params['title'] ) ] );
57        }
58
59        $this->checkTitleUserPermissions( $title, 'read' );
60
61        $this->sanitizeJson( $title, $params['text'] );
62    }
63
64    /**
65     * @param Title $title
66     * @param string $text
67     */
68    private function sanitizeJson( Title $title, string $text ): void {
69        $parserOptions = new ParserOptions( $this->getUser() );
70        $parser = $this->parserFactory->getInstance();
71        $parser->startExternalParse( $title, $parserOptions, Parser::OT_HTML );
72        $parser->setPage( $title );
73        $simpleStyle = new SimpleStyleParser(
74            new MediaWikiWikitextParser( $parser ),
75            [ 'saveUnparsed' => true ]
76        );
77        $status = $simpleStyle->parse( $text );
78        if ( !$status->isOK() ) {
79            $error = Status::wrap( $status )->getHTML( false, false, $this->getLanguage() );
80            $this->getResult()->addValue( null, $this->getModuleName(), [ 'error' => $error ] );
81        } else {
82            $data = $status->getValue()['data'];
83            SimpleStyleParser::updateMarkerSymbolCounters( $data );
84            $this->getResult()
85                ->addValue( null,
86                    $this->getModuleName(),
87                    [ 'sanitized' => FormatJson::encode( $data, false, FormatJson::ALL_OK ) ]
88                );
89        }
90    }
91
92    /** @inheritDoc */
93    public function getAllowedParams() {
94        return [
95            'title' => [
96                ParamValidator::PARAM_TYPE => 'string',
97                ParamValidator::PARAM_DEFAULT => 'Dummy title (called from ' . __CLASS__ . ')',
98            ],
99            'text' => [
100                ParamValidator::PARAM_TYPE => 'text',
101                ParamValidator::PARAM_REQUIRED => true,
102            ]
103        ];
104    }
105
106    /** @inheritDoc */
107    public function mustBePosted() {
108        return true;
109    }
110
111    /** @inheritDoc */
112    protected function getExamplesMessages() {
113        return [
114            'action=sanitize-mapdata&text={"foo":"bar"}' => 'apihelp-sanitize-mapdata-example',
115        ];
116    }
117
118    /**
119     * Indicate that this API can change at any time
120     * @return bool
121     */
122    public function isInternal() {
123        return true;
124    }
125}