Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 95 |
|
0.00% |
0 / 10 |
CRAP | |
0.00% |
0 / 1 |
SpecialThanks | |
0.00% |
0 / 95 |
|
0.00% |
0 / 10 |
1122 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
doesWrites | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
setParameter | |
0.00% |
0 / 23 |
|
0.00% |
0 / 1 |
132 | |||
getFormFields | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
2 | |||
preHtml | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
56 | |||
alterForm | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
20 | |||
getDisplayFormat | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
onSubmit | |
0.00% |
0 / 28 |
|
0.00% |
0 / 1 |
20 | |||
onSuccess | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
isListed | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\Thanks; |
4 | |
5 | use MediaWiki\Api\ApiMain; |
6 | use MediaWiki\Api\ApiUsageException; |
7 | use MediaWiki\HTMLForm\HTMLForm; |
8 | use MediaWiki\Linker\Linker; |
9 | use MediaWiki\Request\DerivativeRequest; |
10 | use MediaWiki\SpecialPage\FormSpecialPage; |
11 | use MediaWiki\Status\Status; |
12 | use MediaWiki\User\UserFactory; |
13 | use MediaWiki\User\UserRigorOptions; |
14 | |
15 | class SpecialThanks extends FormSpecialPage { |
16 | |
17 | /** |
18 | * API result |
19 | */ |
20 | protected array $result; |
21 | |
22 | /** |
23 | * 'rev' for revision, 'log' for log entry, or 'flow' for Flow comment, |
24 | * null if no ID is specified |
25 | */ |
26 | protected ?string $type; |
27 | |
28 | /** |
29 | * Revision or Log ID ('0' = invalid) or Flow UUID |
30 | */ |
31 | protected ?string $id; |
32 | |
33 | private UserFactory $userFactory; |
34 | |
35 | public function __construct( UserFactory $userFactory ) { |
36 | parent::__construct( 'Thanks' ); |
37 | $this->userFactory = $userFactory; |
38 | $this->id = null; |
39 | } |
40 | |
41 | public function doesWrites(): bool { |
42 | return true; |
43 | } |
44 | |
45 | /** |
46 | * Set the type and ID or UUID of the request. |
47 | * @param string $par The subpage name. |
48 | */ |
49 | protected function setParameter( $par ) { |
50 | if ( $par === null || $par === '' ) { |
51 | $this->type = null; |
52 | return; |
53 | } |
54 | |
55 | $tokens = explode( '/', $par ); |
56 | if ( $tokens[0] === 'Flow' ) { |
57 | if ( count( $tokens ) === 1 || $tokens[1] === '' ) { |
58 | $this->type = null; |
59 | return; |
60 | } |
61 | $this->type = 'flow'; |
62 | $this->id = $tokens[1]; |
63 | return; |
64 | } |
65 | |
66 | if ( strtolower( $tokens[0] ) === 'log' ) { |
67 | $this->type = 'log'; |
68 | // Make sure there's a numeric ID specified as the subpage. |
69 | if ( count( $tokens ) === 1 || $tokens[1] === '' || !( ctype_digit( $tokens[1] ) ) ) { |
70 | $this->id = '0'; |
71 | return; |
72 | } |
73 | $this->id = $tokens[1]; |
74 | return; |
75 | } |
76 | |
77 | $this->type = 'rev'; |
78 | if ( !( ctype_digit( $par ) ) ) { |
79 | // Revision ID is not an integer. |
80 | $this->id = '0'; |
81 | return; |
82 | } |
83 | |
84 | $this->id = $par; |
85 | } |
86 | |
87 | /** |
88 | * HTMLForm fields |
89 | * @return string[][] |
90 | */ |
91 | protected function getFormFields(): array { |
92 | return [ |
93 | 'id' => [ |
94 | 'id' => 'mw-thanks-form-id', |
95 | 'name' => 'id', |
96 | 'type' => 'hidden', |
97 | 'default' => $this->id ?? '', |
98 | ], |
99 | 'type' => [ |
100 | 'id' => 'mw-thanks-form-type', |
101 | 'name' => 'type', |
102 | 'type' => 'hidden', |
103 | 'default' => $this->type ?? '', |
104 | ], |
105 | ]; |
106 | } |
107 | |
108 | /** |
109 | * Return the confirmation or error message. |
110 | */ |
111 | protected function preHtml(): string { |
112 | if ( $this->type === null ) { |
113 | $msgKey = 'thanks-error-no-id-specified'; |
114 | } elseif ( $this->type === 'rev' && $this->id === '0' ) { |
115 | $msgKey = 'thanks-error-invalidrevision'; |
116 | } elseif ( $this->type === 'log' && $this->id === '0' ) { |
117 | $msgKey = 'thanks-error-invalid-log-id'; |
118 | } elseif ( $this->type === 'flow' ) { |
119 | $msgKey = 'flow-thanks-confirmation-special'; |
120 | } else { |
121 | // The following messages are used here |
122 | // * thanks-confirmation-special-rev |
123 | // * thanks-confirmation-special-log |
124 | $msgKey = 'thanks-confirmation-special-' . $this->type; |
125 | } |
126 | return '<p>' . $this->msg( $msgKey )->escaped() . '</p>'; |
127 | } |
128 | |
129 | /** |
130 | * Format the submission form. |
131 | * @param HTMLForm $form The form object to modify. |
132 | */ |
133 | protected function alterForm( HTMLForm $form ) { |
134 | if ( $this->type === null |
135 | || ( in_array( $this->type, [ 'rev', 'log' ] ) && $this->id === '0' ) |
136 | ) { |
137 | $form->suppressDefaultSubmit( true ); |
138 | } else { |
139 | $form->setSubmitText( $this->msg( 'thanks-submit' )->escaped() ); |
140 | } |
141 | } |
142 | |
143 | protected function getDisplayFormat(): string { |
144 | return 'ooui'; |
145 | } |
146 | |
147 | /** |
148 | * Call the API internally. |
149 | * @param string[] $data The form data. |
150 | */ |
151 | public function onSubmit( array $data ): Status { |
152 | if ( !isset( $data['id'] ) ) { |
153 | return Status::newFatal( 'thanks-error-invalidrevision' ); |
154 | } |
155 | |
156 | if ( in_array( $this->type, [ 'rev', 'log' ] ) ) { |
157 | $requestData = [ |
158 | 'action' => 'thank', |
159 | $this->type => (int)$data['id'], |
160 | 'source' => 'specialpage', |
161 | 'token' => $this->getOutput()->getCsrfTokenSet()->getToken(), |
162 | ]; |
163 | } else { |
164 | $requestData = [ |
165 | 'action' => 'flowthank', |
166 | 'postid' => $data['id'], |
167 | 'token' => $this->getOutput()->getCsrfTokenSet()->getToken(), |
168 | ]; |
169 | } |
170 | |
171 | $request = new DerivativeRequest( |
172 | $this->getRequest(), |
173 | $requestData, |
174 | true |
175 | ); |
176 | |
177 | $api = new ApiMain( |
178 | $request, |
179 | true |
180 | ); |
181 | |
182 | try { |
183 | $api->execute(); |
184 | } catch ( ApiUsageException $e ) { |
185 | return Status::wrap( $e->getStatusValue() ); |
186 | } |
187 | |
188 | $this->result = $api->getResult()->getResultData( [ 'result' ] ); |
189 | return Status::newGood(); |
190 | } |
191 | |
192 | /** |
193 | * Display a message to the user. |
194 | */ |
195 | public function onSuccess() { |
196 | $sender = $this->getUser(); |
197 | $recipient = $this->userFactory->newFromName( $this->result['recipient'], UserRigorOptions::RIGOR_NONE ); |
198 | $link = Linker::userLink( $recipient->getId(), $recipient->getName() ); |
199 | |
200 | if ( in_array( $this->type, [ 'rev', 'log' ] ) ) { |
201 | $msgKey = 'thanks-thanked-notice'; |
202 | } else { |
203 | $msgKey = 'flow-thanks-thanked-notice'; |
204 | } |
205 | $msg = $this->msg( $msgKey ) |
206 | ->rawParams( $link ) |
207 | ->params( $recipient->getName(), $sender->getName() ); |
208 | $this->getOutput()->addHTML( $msg->parse() ); |
209 | } |
210 | |
211 | public function isListed(): bool { |
212 | return false; |
213 | } |
214 | } |