Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
72.41% |
21 / 29 |
|
60.00% |
3 / 5 |
CRAP | |
0.00% |
0 / 1 |
RestStatusTrait | |
72.41% |
21 / 29 |
|
60.00% |
3 / 5 |
13.54 | |
0.00% |
0 / 1 |
getMessageValueConverter | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
convertStatusToMessageValues | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
1 | |||
throwExceptionForStatus | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
2 | |||
getStatusErrorKeys | |
55.56% |
5 / 9 |
|
0.00% |
0 / 1 |
7.19 | |||
logStatusError | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Rest\Handler\Helper; |
4 | |
5 | use MediaWiki\Logger\LoggerFactory; |
6 | use MediaWiki\Message\Converter; |
7 | use MediaWiki\Message\Message; |
8 | use MediaWiki\Rest\LocalizedHttpException; |
9 | use MessageSpecifier; |
10 | use StatusValue; |
11 | use Wikimedia\Message\MessageValue; |
12 | |
13 | /** |
14 | * Trait for handling Status objects in REST handlers. |
15 | */ |
16 | trait RestStatusTrait { |
17 | |
18 | private ?Converter $messageValueConverter = null; |
19 | |
20 | private function getMessageValueConverter(): Converter { |
21 | if ( !$this->messageValueConverter ) { |
22 | $this->messageValueConverter = new Converter(); |
23 | } |
24 | return $this->messageValueConverter; |
25 | } |
26 | |
27 | /** |
28 | * Extract the error messages from a Status, as MessageValue objects. |
29 | * @param StatusValue $status |
30 | * @return MessageValue[] |
31 | */ |
32 | private function convertStatusToMessageValues( StatusValue $status ): array { |
33 | $conv = $this->getMessageValueConverter(); |
34 | return array_map( static function ( $error ) use ( $conv ) { |
35 | // TODO: It should be possible to do this without going through a Message object, |
36 | // but the internal format of parameters is different in MessageValue (T358779) |
37 | return $conv->convertMessage( |
38 | Message::newFromSpecifier( [ $error['message'], ...$error['params'], ] ) |
39 | ); |
40 | }, $status->getErrors() ); |
41 | } |
42 | |
43 | /** |
44 | * @param StatusValue $status |
45 | * @param string|MessageValue $msg |
46 | * @param int $code |
47 | * @param array $data |
48 | * |
49 | * @return never |
50 | * @throws LocalizedHttpException |
51 | */ |
52 | private function throwExceptionForStatus( |
53 | StatusValue $status, |
54 | $msg, |
55 | int $code, |
56 | array $data = [] |
57 | ) { |
58 | $data += [ 'error-keys' => $this->getStatusErrorKeys( $status ) ]; |
59 | |
60 | if ( is_string( $msg ) ) { |
61 | $msg = MessageValue::new( $msg ) |
62 | ->semicolonListParams( |
63 | $this->convertStatusToMessageValues( $status ) |
64 | ); |
65 | } |
66 | |
67 | throw new LocalizedHttpException( $msg, $code, $data ); |
68 | } |
69 | |
70 | private function getStatusErrorKeys( StatusValue $status ) { |
71 | $keys = []; |
72 | |
73 | foreach ( $status->getErrors() as [ 'message' => $msg ] ) { |
74 | if ( is_string( $msg ) ) { |
75 | $keys[] = $msg; |
76 | } elseif ( is_array( $msg ) ) { |
77 | $keys[] = $msg[0]; |
78 | } elseif ( $msg instanceof MessageSpecifier ) { |
79 | $keys[] = $msg->getKey(); |
80 | } |
81 | } |
82 | |
83 | return array_unique( $keys ); |
84 | } |
85 | |
86 | private function logStatusError( StatusValue $status, string $message, string $channel ) { |
87 | LoggerFactory::getInstance( $channel )->error( |
88 | $message, |
89 | [ 'reason' => $this->getStatusErrorKeys( $status ) ] |
90 | ); |
91 | } |
92 | |
93 | } |