Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
95.16% covered (success)
95.16%
59 / 62
50.00% covered (danger)
50.00%
2 / 4
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiFormatJson
95.16% covered (success)
95.16%
59 / 62
50.00% covered (danger)
50.00%
2 / 4
16
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 getMimeType
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 execute
93.10% covered (success)
93.10%
27 / 29
0.00% covered (danger)
0.00%
0 / 1
10.03
 getAllowedParams
96.00% covered (success)
96.00%
24 / 25
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Copyright © 2006 Yuri Astrakhan "<Firstname><Lastname>@gmail.com"
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 */
22
23use Wikimedia\ParamValidator\ParamValidator;
24
25/**
26 * API JSON output formatter
27 * @ingroup API
28 */
29class ApiFormatJson extends ApiFormatBase {
30
31    private $isRaw;
32
33    public function __construct( ApiMain $main, $format ) {
34        parent::__construct( $main, $format );
35        $this->isRaw = ( $format === 'rawfm' );
36
37        if ( $this->getMain()->getCheck( 'callback' ) ) {
38            # T94015: jQuery appends a useless '_' parameter in jsonp mode.
39            # Mark the parameter as used in that case to avoid a warning that's
40            # outside the control of the end user.
41            # (and do it here because ApiMain::reportUnusedParams() gets called
42            # before our ::execute())
43            $this->getMain()->markParamsUsed( '_' );
44        }
45    }
46
47    public function getMimeType() {
48        $params = $this->extractRequestParams();
49        // callback:
50        if ( isset( $params['callback'] ) ) {
51            return 'text/javascript';
52        }
53
54        return 'application/json';
55    }
56
57    public function execute() {
58        $params = $this->extractRequestParams();
59
60        $opt = 0;
61        if ( $this->isRaw ) {
62            $opt |= FormatJson::ALL_OK;
63            $transform = [];
64        } else {
65            switch ( $params['formatversion'] ) {
66                case 1:
67                    $opt |= $params['utf8'] ? FormatJson::ALL_OK : FormatJson::XMLMETA_OK;
68                    $transform = [
69                        'BC' => [],
70                        'Types' => [ 'AssocAsObject' => true ],
71                        'Strip' => 'all',
72                    ];
73                    break;
74
75                case 2:
76                case 'latest':
77                    $opt |= $params['ascii'] ? FormatJson::XMLMETA_OK : FormatJson::ALL_OK;
78                    $transform = [
79                        'Types' => [ 'AssocAsObject' => true ],
80                        'Strip' => 'all',
81                    ];
82                    break;
83
84                default:
85                    // Should have been caught during parameter validation
86                    // @codeCoverageIgnoreStart
87                    self::dieDebug( __METHOD__, 'Unknown value for \'formatversion\'' );
88                    // @codeCoverageIgnoreEnd
89            }
90        }
91        $data = $this->getResult()->getResultData( null, $transform );
92        $json = FormatJson::encode( $data, $this->getIsHtml(), $opt );
93        if ( $json === false ) {
94            // This should never happen, but it's a bug which could crop up
95            // if you use ApiResult::NO_VALIDATE for instance.
96            // @codeCoverageIgnoreStart
97            self::dieDebug( __METHOD__, 'Unable to encode API result as JSON' );
98            // @codeCoverageIgnoreEnd
99        }
100
101        if ( isset( $params['callback'] ) ) {
102            $callback = preg_replace( "/[^][.\\'\\\"_A-Za-z0-9]/", '', $params['callback'] );
103            # Prepend a comment to try to avoid attacks against content
104            # sniffers, such as T70187.
105            $this->printText( "/**/$callback($json)" );
106        } else {
107            $this->printText( $json );
108        }
109    }
110
111    public function getAllowedParams() {
112        if ( $this->isRaw ) {
113            return parent::getAllowedParams();
114        }
115
116        return parent::getAllowedParams() + [
117            'callback' => [
118                ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-callback',
119            ],
120            'utf8' => [
121                ParamValidator::PARAM_DEFAULT => false,
122                ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-utf8',
123            ],
124            'ascii' => [
125                ParamValidator::PARAM_DEFAULT => false,
126                ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-ascii',
127            ],
128            'formatversion' => [
129                ParamValidator::PARAM_TYPE => [ '1', '2', 'latest' ],
130                ParamValidator::PARAM_DEFAULT => '1',
131                ApiBase::PARAM_HELP_MSG => 'apihelp-json-param-formatversion',
132                ApiBase::PARAM_HELP_MSG_PER_VALUE => [
133                    '1' => 'apihelp-json-paramvalue-formatversion-1',
134                    '2' => 'apihelp-json-paramvalue-formatversion-2',
135                    'latest' => 'apihelp-json-paramvalue-formatversion-latest',
136                ],
137            ],
138        ];
139    }
140}