Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
63.33% covered (warning)
63.33%
19 / 30
37.50% covered (danger)
37.50%
3 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
ParamValidatorCallbacks
63.33% covered (warning)
63.33%
19 / 30
37.50% covered (danger)
37.50%
3 / 8
36.80
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
 getParamsFromSource
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
1 / 1
6
 hasParam
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getValue
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
4
 hasUpload
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 getUploadedFile
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
12
 recordCondition
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 useHighLimits
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3namespace MediaWiki\Rest\Validator;
4
5use InvalidArgumentException;
6use MediaWiki\Permissions\Authority;
7use MediaWiki\Rest\RequestInterface;
8use Psr\Http\Message\UploadedFileInterface;
9use UtfNormal\Validator;
10use Wikimedia\Message\DataMessageValue;
11use Wikimedia\ParamValidator\Callbacks;
12
13class ParamValidatorCallbacks implements Callbacks {
14
15    private RequestInterface $request;
16    private Authority $authority;
17
18    public function __construct(
19        RequestInterface $request,
20        Authority $authority
21    ) {
22        $this->request = $request;
23        $this->authority = $authority;
24    }
25
26    /**
27     * Get the raw parameters from a source in the request
28     * @param string $source 'path', 'query', or 'post'
29     * @return array
30     */
31    private function getParamsFromSource( $source ) {
32        // This switch block must match Validator::KNOWN_PARAM_SOURCES
33        switch ( $source ) {
34            case 'path':
35                return $this->request->getPathParams();
36
37            case 'query':
38                return $this->request->getQueryParams();
39
40            case 'post':
41                wfDeprecatedMsg( 'The "post" source is deprecated, use "body" instead', '1.43' );
42                return $this->request->getPostParams();
43
44            case 'body':
45                return $this->request->getParsedBody() ?? [];
46
47            default:
48                throw new InvalidArgumentException( __METHOD__ . ": Invalid source '$source'" );
49        }
50    }
51
52    public function hasParam( $name, array $options ) {
53        $params = $this->getParamsFromSource( $options['source'] );
54        return isset( $params[$name] );
55    }
56
57    public function getValue( $name, $default, array $options ) {
58        $params = $this->getParamsFromSource( $options['source'] );
59        $value = $params[$name] ?? $default;
60
61        // Normalisation for body is being handled in Handler::parseBodyData
62        if ( !isset( $options['raw'] ) && $options['source'] !== 'body' ) {
63            if ( is_string( $value ) ) {
64                // Normalize value to NFC UTF-8
65                $normalizedValue = Validator::cleanUp( $value );
66                // TODO: Warn if normalization was applied
67
68                $value = $normalizedValue;
69            }
70        }
71
72        return $value;
73    }
74
75    public function hasUpload( $name, array $options ) {
76        if ( $options['source'] !== 'post' ) {
77            return false;
78        }
79        return $this->getUploadedFile( $name, $options ) !== null;
80    }
81
82    public function getUploadedFile( $name, array $options ) {
83        if ( $options['source'] !== 'post' ) {
84            return null;
85        }
86        $upload = $this->request->getUploadedFiles()[$name] ?? null;
87        return $upload instanceof UploadedFileInterface ? $upload : null;
88    }
89
90    public function recordCondition(
91        DataMessageValue $message, $name, $value, array $settings, array $options
92    ) {
93        // @todo Figure out how to handle warnings
94    }
95
96    public function useHighLimits( array $options ) {
97        return $this->authority->isAllowed( 'apihighlimits' );
98    }
99
100}