Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 74 |
|
0.00% |
0 / 6 |
CRAP | |
0.00% |
0 / 1 |
RestUtilTrait | |
0.00% |
0 / 74 |
|
0.00% |
0 / 6 |
240 | |
0.00% |
0 / 1 |
die | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
12 | |||
dieIf | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
requireMaxOneParameter | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
6 | |||
requireAtLeastOneParameter | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
6 | |||
requireOnlyOneParameter | |
0.00% |
0 / 30 |
|
0.00% |
0 / 1 |
12 | |||
parameterNotEmpty | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
12 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\ReadingLists\Rest; |
4 | |
5 | use MediaWiki\Message\Converter; |
6 | use MediaWiki\Rest\LocalizedHttpException; |
7 | use Message; |
8 | use Wikimedia\Message\ListParam; |
9 | use Wikimedia\Message\MessageValue; |
10 | use Wikimedia\Message\ParamType; |
11 | |
12 | /** |
13 | * Trait for collecting utility code that is a candidate for moving to the REST infrastructure |
14 | * in MediaWiki core. |
15 | * |
16 | * Much of this code is related to parameter validation that cannot reasonably be expressed in the |
17 | * usual validation functions, especially as related to combinations of parameters. One open |
18 | * question: is validation of this sort actually RESTful? Would including these functions |
19 | * encourage a type of endpoint design that we'd rather not have? |
20 | */ |
21 | trait RestUtilTrait { |
22 | /** |
23 | * @param string|Message|MessageValue $msg |
24 | * @param array $params |
25 | * @param int $code |
26 | * @return never |
27 | * @throws LocalizedHttpException |
28 | */ |
29 | protected function die( $msg, array $params = [], int $code = 400 ) { |
30 | if ( $msg instanceof Message ) { |
31 | $c = new Converter(); |
32 | $mv = $c->convertMessage( $msg ); |
33 | } elseif ( $msg instanceof MessageValue ) { |
34 | $mv = $msg; |
35 | } else { |
36 | $mv = MessageValue::new( $msg, $params ); |
37 | } |
38 | |
39 | throw new LocalizedHttpException( $mv, 400 ); |
40 | } |
41 | |
42 | /** |
43 | * @param bool $condition |
44 | * @param string|Message|MessageValue $msg |
45 | * @param array $params |
46 | * @param int $code |
47 | * @return void |
48 | * @throws LocalizedHttpException |
49 | */ |
50 | protected function dieIf( bool $condition, $msg, array $params = [], int $code = 400 ) { |
51 | if ( $condition ) { |
52 | $this->die( $msg, $params, $code ); |
53 | } |
54 | } |
55 | |
56 | /** |
57 | * Dies if more than one parameter from a certain set of parameters are set and not false. |
58 | * |
59 | * @param array $params User provided parameters set, as from $this->getValidatedParams() |
60 | * @param string ...$required Parameter names that cannot have more than one set |
61 | */ |
62 | protected function requireMaxOneParameter( array $params, ...$required ) { |
63 | $intersection = array_intersect( array_keys( array_filter( $params, |
64 | [ $this, 'parameterNotEmpty' ] ) ), $required ); |
65 | |
66 | if ( count( $intersection ) > 1 ) { |
67 | $lp = new ListParam( |
68 | ParamType::TEXT, |
69 | array_map( |
70 | static function ( $paramName ) { |
71 | return '<var>' . $paramName . '</var>'; |
72 | }, |
73 | array_values( $intersection ) |
74 | ) |
75 | ); |
76 | |
77 | $mv = MessageValue::new( 'apierror-invalidparammix' ) |
78 | ->textListParams( [ $lp ] ) |
79 | ->numParams( count( $intersection ) ); |
80 | throw new LocalizedHttpException( $mv, 400 ); |
81 | } |
82 | } |
83 | |
84 | /** |
85 | * Die if 0 of a certain set of parameters is set and not false. |
86 | * |
87 | * @param array $params User provided parameters set, as from $this->extractRequestParams() |
88 | * @param string ...$required Names of parameters of which at least one must be set |
89 | */ |
90 | protected function requireAtLeastOneParameter( $params, ...$required ) { |
91 | $intersection = array_intersect( |
92 | array_keys( array_filter( $params, [ $this, 'parameterNotEmpty' ] ) ), |
93 | $required |
94 | ); |
95 | |
96 | if ( count( $intersection ) == 0 ) { |
97 | $lp = new ListParam( |
98 | ParamType::TEXT, |
99 | array_map( |
100 | static function ( $paramName ) { |
101 | return '<var>' . $paramName . '</var>'; |
102 | }, |
103 | array_values( $required ) |
104 | ) |
105 | ); |
106 | |
107 | $mv = MessageValue::new( 'apierror-missingparam-at-least-one-of' ) |
108 | ->textListParams( [ $lp ] ) |
109 | ->numParams( count( $required ) ); |
110 | throw new LocalizedHttpException( $mv, 400 ); |
111 | } |
112 | } |
113 | |
114 | /** |
115 | * Die if 0 or more than one of a certain set of parameters is set and not false. |
116 | * |
117 | * @param array $params User provided parameter set, as from $this->extractRequestParams() |
118 | * @param string ...$required Names of parameters of which exactly one must be set |
119 | * @throws LocalizedHttpException |
120 | */ |
121 | protected function requireOnlyOneParameter( $params, ...$required ) { |
122 | $intersection = array_intersect( array_keys( array_filter( $params, |
123 | [ $this, 'parameterNotEmpty' ] ) ), $required ); |
124 | |
125 | if ( count( $intersection ) > 1 ) { |
126 | $lp = new ListParam( |
127 | ParamType::TEXT, |
128 | array_map( |
129 | static function ( $paramName ) { |
130 | return '<var>' . $paramName . '</var>'; |
131 | }, |
132 | array_values( $intersection ) |
133 | ) |
134 | ); |
135 | |
136 | $mv = MessageValue::new( 'apierror-invalidparammix' ) |
137 | ->textListParams( [ $lp ] ) |
138 | ->numParams( count( $intersection ) ); |
139 | throw new LocalizedHttpException( $mv, 400 ); |
140 | } elseif ( count( $intersection ) == 0 ) { |
141 | $lp = new ListParam( |
142 | ParamType::TEXT, |
143 | array_map( |
144 | static function ( $paramName ) { |
145 | return '<var>' . $paramName . '</var>'; |
146 | }, |
147 | array_values( $required ) |
148 | ) |
149 | ); |
150 | |
151 | $mv = MessageValue::new( 'apierror-missingparam-one-of' ) |
152 | ->textListParams( [ $lp ] ) |
153 | ->numParams( count( $required ) ); |
154 | throw new LocalizedHttpException( $mv, 400 ); |
155 | } |
156 | } |
157 | |
158 | /** |
159 | * Callback function used in requireOnlyOneParameter to check whether required parameters are set. |
160 | * |
161 | * @param mixed $x Parameter to check is not null/false/empty string |
162 | * @return bool |
163 | */ |
164 | protected function parameterNotEmpty( $x ): bool { |
165 | return $x !== null && $x !== false && $x !== ''; |
166 | } |
167 | } |