Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.33% covered (success)
98.33%
59 / 60
85.71% covered (warning)
85.71%
6 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
ApiParamValidatorCallbacks
98.33% covered (success)
98.33%
59 / 60
85.71% covered (warning)
85.71%
6 / 7
19
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 hasParam
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getValue
90.91% covered (success)
90.91%
10 / 11
0.00% covered (danger)
0.00%
0 / 1
5.02
 hasUpload
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getUploadedFile
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
2
 recordCondition
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
1 / 1
8
 useHighLimits
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3namespace MediaWiki\Api\Validator;
4
5use MediaWiki\Api\ApiBase;
6use MediaWiki\Api\ApiMain;
7use Wikimedia\Message\DataMessageValue;
8use Wikimedia\ParamValidator\Callbacks;
9use Wikimedia\ParamValidator\Util\UploadedFile;
10
11/**
12 * ParamValidator callbacks for the Action API
13 * @since 1.35
14 * @ingroup API
15 */
16class ApiParamValidatorCallbacks implements Callbacks {
17
18    /** @var ApiMain */
19    private $apiMain;
20
21    /**
22     * @internal
23     * @param ApiMain $main
24     */
25    public function __construct( ApiMain $main ) {
26        $this->apiMain = $main;
27    }
28
29    public function hasParam( $name, array $options ) {
30        return $this->apiMain->getCheck( $name );
31    }
32
33    public function getValue( $name, $default, array $options ) {
34        $value = $this->apiMain->getVal( $name, $default );
35        $request = $this->apiMain->getRequest();
36        $rawValue = $request->getRawVal( $name );
37
38        if ( $options['raw'] ?? false ) {
39            // Bypass NFC normalization
40            return $rawValue;
41        }
42        if ( is_string( $rawValue ) ) {
43            // Preserve U+001F for multi-values
44            if ( substr( $rawValue, 0, 1 ) === "\x1f" ) {
45                // This loses the potential checkTitleEncoding() transformation done by
46                // WebRequest for $_GET. Let's call that a feature.
47                $value = implode( "\x1f", $request->normalizeUnicode( explode( "\x1f", $rawValue ) ) );
48            }
49
50            // Check for NFC normalization, and warn
51            if ( $rawValue !== $value ) {
52                $options['module']->handleParamNormalization( $name, $value, $rawValue );
53            }
54        }
55
56        return $value;
57    }
58
59    public function hasUpload( $name, array $options ) {
60        return $this->getUploadedFile( $name, $options ) !== null;
61    }
62
63    public function getUploadedFile( $name, array $options ) {
64        $upload = $this->apiMain->getUpload( $name );
65        if ( !$upload->exists() ) {
66            return null;
67        }
68        return new UploadedFile( [
69            'error' => $upload->getError(),
70            'tmp_name' => $upload->getTempName(),
71            'size' => $upload->getSize(),
72            'name' => $upload->getName(),
73            'type' => $upload->getType(),
74        ] );
75    }
76
77    public function recordCondition(
78        DataMessageValue $message, $name, $value, array $settings, array $options
79    ) {
80        /** @var ApiBase $module */
81        $module = $options['module'];
82
83        $code = $message->getCode();
84        switch ( $code ) {
85            case 'param-deprecated': // @codeCoverageIgnore
86            case 'deprecated-value': // @codeCoverageIgnore
87                if ( $code === 'param-deprecated' ) {
88                    $feature = $name;
89                } else {
90                    $feature = $name . '=' . $value;
91                    $data = $message->getData() ?? [];
92                    if ( isset( $data['💩'] ) ) {
93                        // This is from an old-style Message. Strip out ParamValidator's added params.
94                        unset( $data['💩'] );
95                        $message = DataMessageValue::new(
96                            $message->getKey(),
97                            array_slice( $message->getParams(), 2 ),
98                            $code,
99                            $data
100                        );
101                    }
102                }
103
104                $m = $module;
105                while ( !$m->isMain() ) {
106                    $p = $m->getParent();
107                    $mName = $m->getModuleName();
108                    $mParam = $p->encodeParamName( $p->getModuleManager()->getModuleGroup( $mName ) );
109                    $feature = "{$mParam}={$mName}&{$feature}";
110                    $m = $p;
111                }
112                $module->addDeprecation(
113                    $message,
114                    $feature,
115                    $message->getData()
116                );
117                break;
118
119            case 'param-sensitive': // @codeCoverageIgnore
120                $module->getMain()->markParamsSensitive( $name );
121                break;
122
123            default:
124                $module->addWarning(
125                    $message,
126                    $message->getCode(),
127                    $message->getData()
128                );
129                break;
130        }
131    }
132
133    public function useHighLimits( array $options ) {
134        return $this->apiMain->canApiHighLimits();
135    }
136
137}