Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 121 |
|
0.00% |
0 / 11 |
CRAP | |
0.00% |
0 / 1 |
SpecialNotifyTranslators | |
0.00% |
0 / 121 |
|
0.00% |
0 / 11 |
420 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
doesWrites | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getGroupName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getMessagePrefix | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDisplayFormat | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
alterForm | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
getFormFields | |
0.00% |
0 / 66 |
|
0.00% |
0 / 1 |
12 | |||
getTranslatablePages | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
12 | |||
getSourceLanguage | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
onSubmit | |
0.00% |
0 / 32 |
|
0.00% |
0 / 1 |
42 | |||
onSuccess | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | declare( strict_types = 1 ); |
3 | |
4 | namespace MediaWiki\Extension\TranslationNotifications; |
5 | |
6 | use ErrorPageError; |
7 | use JobQueueGroup; |
8 | use LogicException; |
9 | use MediaWiki\Extension\Translate\MessageGroupProcessing\MessageGroups; |
10 | use MediaWiki\Extension\Translate\PageTranslation\TranslatablePage; |
11 | use MediaWiki\Extension\TranslationNotifications\Jobs\TranslationNotificationsSubmitJob; |
12 | use MediaWiki\Extension\TranslationNotifications\Utilities\LanguageSet; |
13 | use MediaWiki\Extension\TranslationNotifications\Utilities\NotificationMessageBuilder; |
14 | use MediaWiki\HTMLForm\HTMLForm; |
15 | use MediaWiki\Languages\LanguageNameUtils; |
16 | use MediaWiki\SpecialPage\FormSpecialPage; |
17 | use MediaWiki\Status\Status; |
18 | use MediaWiki\Title\Title; |
19 | use WikiPageMessageGroup; |
20 | |
21 | /** |
22 | * Form for translation managers to send a notification |
23 | * to registered translators. |
24 | * |
25 | * @author Amir E. Aharoni |
26 | * @author Santhosh Thottingal |
27 | * @author Niklas Laxström |
28 | * @author Siebrand Mazeland |
29 | * @copyright Copyright © 2012, Amir E. Aharoni, Santhosh Thottingal |
30 | * @license GPL-2.0-or-later |
31 | * @ingroup SpecialPage TranslateSpecialPage |
32 | */ |
33 | class SpecialNotifyTranslators extends FormSpecialPage { |
34 | public static string $right = 'translate-manage'; |
35 | private LanguageNameUtils $languageNameUtils; |
36 | private JobQueueGroup $jobQueueGroup; |
37 | |
38 | public function __construct( |
39 | LanguageNameUtils $languageNameUtils, |
40 | JobQueueGroup $jobQueueGroup |
41 | ) { |
42 | parent::__construct( 'NotifyTranslators', self::$right ); |
43 | $this->languageNameUtils = $languageNameUtils; |
44 | $this->jobQueueGroup = $jobQueueGroup; |
45 | } |
46 | |
47 | public function doesWrites(): bool { |
48 | return true; |
49 | } |
50 | |
51 | protected function getGroupName(): string { |
52 | return 'translation'; |
53 | } |
54 | |
55 | protected function getMessagePrefix(): string { |
56 | return 'translationnotifications'; |
57 | } |
58 | |
59 | protected function getDisplayFormat(): string { |
60 | return 'ooui'; |
61 | } |
62 | |
63 | protected function alterForm( HTMLForm $form ): void { |
64 | $form->setId( 'notifytranslators-form' ); |
65 | $form->setSubmitID( 'translationnotifications-send-notification-button' ); |
66 | $form->setSubmitTextMsg( 'translationnotifications-send-notification-button' ); |
67 | } |
68 | |
69 | /** |
70 | * Get the form fields for use by the HTMLForm. |
71 | * We also set up the JavaScript needed on the form here. |
72 | * |
73 | * @return array |
74 | * @throws ErrorPageError if there is no translatable page on this wiki |
75 | */ |
76 | protected function getFormFields(): array { |
77 | $this->getOutput()->addModules( 'ext.translationnotifications.notifytranslators' ); |
78 | |
79 | $formFields = []; |
80 | |
81 | $pages = $this->getTranslatablePages(); |
82 | if ( count( $pages ) === 0 ) { |
83 | throw new ErrorPageError( 'notifytranslators', |
84 | 'translationnotifications-error-no-translatable-pages' ); |
85 | } |
86 | |
87 | $formFields['TranslatablePage'] = [ |
88 | 'name' => 'tpage', |
89 | 'id' => 'mw-tns-group-selector', |
90 | 'type' => 'select', |
91 | 'label-message' => [ 'translationnotifications-translatablepage-title' ], |
92 | 'options' => $pages, |
93 | 'cssclass' => 'mw-tns-translatable-page-selector', |
94 | 'default' => '', |
95 | 'required' => true |
96 | ]; |
97 | |
98 | $languages = array_flip( |
99 | $this->languageNameUtils->getLanguageNames( $this->getLanguage()->getCode() ) |
100 | ); |
101 | |
102 | $formFields['LanguageSet'] = [ |
103 | 'name' => 'notifiable-languages-options', |
104 | 'type' => 'radio', |
105 | 'default' => LanguageSet::ALL, |
106 | 'label-message' => 'translationnotifications-requested-languages-label', |
107 | 'options-messages' => [ |
108 | 'translationnotifications-languages-to-notify-all-label' |
109 | => LanguageSet::ALL, |
110 | 'translationnotifications-languages-to-notify-only-selected-label' |
111 | => LanguageSet::SOME, |
112 | 'translationnotifications-languages-to-notify-all-except-label' |
113 | => LanguageSet::ALL_EXCEPT_SOME |
114 | ] |
115 | ]; |
116 | |
117 | // Selected languages input box |
118 | $formFields['SelectedLanguages'] = [ |
119 | 'type' => 'multiselect', |
120 | 'dropdown' => true, |
121 | 'label-message' => 'translationnotifications-languages-to-notify-label', |
122 | 'help-message' => 'translationnotifications-languages-to-notify-label-help-message', |
123 | 'options' => $languages, |
124 | 'hide-if' => [ '===', 'LanguageSet', (string)LanguageSet::ALL ] |
125 | ]; |
126 | |
127 | // Priority dropdown |
128 | $priorityOptions = []; |
129 | $priorities = [ 'unset', 'high', 'medium', 'low' ]; |
130 | |
131 | foreach ( $priorities as $priority ) { |
132 | $priorityMessage = |
133 | NotificationMessageBuilder::getPriorityMessage( $priority ) |
134 | ->setContext( $this->getContext() )->text(); |
135 | $priorityOptions[$priorityMessage] = $priority; |
136 | } |
137 | |
138 | $formFields['Priority'] = [ |
139 | 'type' => 'select', |
140 | 'label-message' => [ 'translationnotifications-priority' ], |
141 | 'options' => $priorityOptions, |
142 | 'default' => 'unset', |
143 | ]; |
144 | |
145 | // Deadline date input box with datepicker |
146 | $formFields['DeadlineDate'] = [ |
147 | 'type' => 'date', |
148 | 'min' => date( 'Y-m-d' ), |
149 | 'label-message' => 'translationnotifications-deadline-label', |
150 | 'help-message' => 'translationnotifications-deadline-help-message', |
151 | ]; |
152 | |
153 | // Custom text |
154 | $formFields['NotificationText'] = [ |
155 | 'type' => 'textarea', |
156 | 'rows' => 20, |
157 | 'label-message' => 'emailmessage', |
158 | ]; |
159 | |
160 | return $formFields; |
161 | } |
162 | |
163 | protected function getTranslatablePages(): array { |
164 | $translatablePages = MessageGroups::getGroupsByType( WikiPageMessageGroup::class ); |
165 | usort( $translatablePages, [ MessageGroups::class, 'groupLabelSort' ] ); |
166 | |
167 | $options = [ |
168 | // Default value |
169 | '' => '' |
170 | ]; |
171 | foreach ( $translatablePages as $page ) { |
172 | if ( MessageGroups::getPriority( $page ) === 'discouraged' ) { |
173 | continue; |
174 | } |
175 | $options[$page->getTitle()->getPrefixedText()] = $page->getId(); |
176 | } |
177 | |
178 | return $options; |
179 | } |
180 | |
181 | private function getSourceLanguage( Title $title ): string { |
182 | $translatablePage = TranslatablePage::newFromTitle( $title ); |
183 | return $translatablePage->getMessageGroup()->getSourceLanguage(); |
184 | } |
185 | |
186 | public function onSubmit( array $formData ): Status { |
187 | $group = MessageGroups::getGroup( $formData['TranslatablePage'] ); |
188 | if ( !$group instanceof WikiPageMessageGroup ) { |
189 | throw new LogicException( 'Cannot send notification to non-translatable pages.' ); |
190 | } |
191 | |
192 | $translatablePageTitle = $group->getTitle(); |
193 | $notificationText = $formData['NotificationText']; |
194 | $priority = $formData['Priority']; |
195 | $deadlineDate = $formData['DeadlineDate']; |
196 | $selectedLanguages = $formData['SelectedLanguages']; |
197 | $pageSourceLangCode = $this->getSourceLanguage( $translatablePageTitle ); |
198 | $notificationLanguages = []; |
199 | |
200 | // The default is not to specify any languages and to send the notification to speakers of |
201 | // all the languages except the source language. When no languages are specified, |
202 | // an empty string will be sent here and an appropriate message will be shown in the log. |
203 | if ( count( $selectedLanguages ) ) { |
204 | // Filter out the source language |
205 | foreach ( $selectedLanguages as $langCode ) { |
206 | if ( $langCode !== $pageSourceLangCode ) { |
207 | $notificationLanguages[] = $langCode; |
208 | } |
209 | } |
210 | |
211 | if ( $notificationLanguages === [] ) { |
212 | return Status::newFatal( 'translationnotifications-sourcelang-only' ); |
213 | } |
214 | } |
215 | $languageSet = new LanguageSet( (int)$formData['LanguageSet'] ); |
216 | |
217 | $requestData = [ |
218 | 'notificationText' => $notificationText, |
219 | 'priority' => $priority, |
220 | 'deadlineDate' => $deadlineDate, |
221 | 'selectedLanguages' => $selectedLanguages, |
222 | 'languageSet' => $languageSet->jsonSerialize(), |
223 | ]; |
224 | |
225 | $job = TranslationNotificationsSubmitJob::newJob( |
226 | $translatablePageTitle, |
227 | $requestData, |
228 | $this->getUser()->getId(), |
229 | $this->getLanguage()->getCode() |
230 | ); |
231 | |
232 | $this->jobQueueGroup->push( $job ); |
233 | return Status::newGood(); |
234 | } |
235 | |
236 | public function onSuccess(): void { |
237 | $this->getOutput()->addWikiMsg( 'translationnotifications-submit-ok' ); |
238 | } |
239 | } |