Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 153 |
|
0.00% |
0 / 9 |
CRAP | |
0.00% |
0 / 1 |
DisplayGroupSynchronizationInfo | |
0.00% |
0 / 153 |
|
0.00% |
0 / 9 |
462 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getGroupsInSyncHtml | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
12 | |||
getHtmlForGroupsWithError | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
12 | |||
addGroupSyncHelp | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
2 | |||
getGroupSyncInfoHtml | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
6 | |||
getHtmlForGroupErrors | |
0.00% |
0 / 35 |
|
0.00% |
0 / 1 |
6 | |||
getErrorMessageHtml | |
0.00% |
0 / 28 |
|
0.00% |
0 / 1 |
6 | |||
getMessageInfoHtml | |
0.00% |
0 / 36 |
|
0.00% |
0 / 1 |
42 | |||
getMessagePropHtml | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | declare( strict_types = 1 ); |
3 | |
4 | namespace MediaWiki\Extension\Translate\Synchronization; |
5 | |
6 | use Language; |
7 | use MediaWiki\Html\Html; |
8 | use MediaWiki\Linker\LinkRenderer; |
9 | use MediaWiki\Title\Title; |
10 | use MessageLocalizer; |
11 | |
12 | /** |
13 | * Display Group synchronization related information |
14 | * @author Abijeet Patro |
15 | * @license GPL-2.0-or-later |
16 | * @since 2021.02 |
17 | */ |
18 | class DisplayGroupSynchronizationInfo { |
19 | /** @var MessageLocalizer */ |
20 | private $localizer; |
21 | /** @var LinkRenderer */ |
22 | private $linkRenderer; |
23 | |
24 | public function __construct( MessageLocalizer $localizer, LinkRenderer $linkRenderer ) { |
25 | $this->localizer = $localizer; |
26 | $this->linkRenderer = $linkRenderer; |
27 | } |
28 | |
29 | /** @param string[] $groupsInSync */ |
30 | public function getGroupsInSyncHtml( array $groupsInSync, string $wrapperClass ): string { |
31 | sort( $groupsInSync ); |
32 | |
33 | if ( !$groupsInSync ) { |
34 | return Html::rawElement( |
35 | 'p', |
36 | [ 'class' => $wrapperClass ], |
37 | $this->localizer->msg( 'translate-smg-no-groups-in-sync' )->escaped() |
38 | . $this->addGroupSyncHelp( $wrapperClass ) |
39 | ); |
40 | } |
41 | |
42 | $htmlGroupItems = []; |
43 | foreach ( $groupsInSync as $groupId ) { |
44 | $htmlGroupItems[] = Html::element( 'li', [], $groupId ); |
45 | } |
46 | |
47 | return $this->getGroupSyncInfoHtml( |
48 | $wrapperClass, |
49 | 'translate-smg-groups-in-sync', |
50 | 'translate-smg-groups-in-sync-list', |
51 | Html::rawElement( 'ul', [], implode( '', $htmlGroupItems ) ), |
52 | $this->addGroupSyncHelp( $wrapperClass ) |
53 | ); |
54 | } |
55 | |
56 | public function getHtmlForGroupsWithError( |
57 | GroupSynchronizationCache $groupSynchronizationCache, |
58 | string $wrapperClass, |
59 | Language $currentLang |
60 | ): string { |
61 | $groupsWithErrors = $groupSynchronizationCache->getGroupsWithErrors(); |
62 | if ( !$groupsWithErrors ) { |
63 | return ''; |
64 | } |
65 | |
66 | $htmlGroupItems = []; |
67 | foreach ( $groupsWithErrors as $groupId ) { |
68 | $groupErrorResponse = $groupSynchronizationCache->getGroupErrorInfo( $groupId ); |
69 | $htmlGroupItems[] = $this->getHtmlForGroupErrors( $groupErrorResponse, $currentLang, $wrapperClass ); |
70 | } |
71 | |
72 | return $this->getGroupSyncInfoHtml( |
73 | $wrapperClass . ' js-group-sync-groups-with-error', |
74 | 'translate-smg-groups-with-error-title', |
75 | 'translate-smg-groups-with-error-desc', |
76 | implode( '', $htmlGroupItems ) |
77 | ); |
78 | } |
79 | |
80 | private function addGroupSyncHelp( string $wrapperClass ): string { |
81 | return Html::element( |
82 | 'a', |
83 | [ |
84 | 'href' => 'https://www.mediawiki.org/wiki/Special:MyLanguage/Help:Extension:Translate/' . |
85 | 'Group_management#Strong_synchronization', |
86 | 'target' => '_blank', |
87 | 'class' => "{$wrapperClass}__help", |
88 | ], |
89 | '[' . $this->localizer->msg( 'translate-smg-strong-sync-help' )->text() . ']' |
90 | ); |
91 | } |
92 | |
93 | private function getGroupSyncInfoHtml( |
94 | string $className, |
95 | string $summaryMsgKey, |
96 | string $descriptionMsgKey, |
97 | string $htmlContent, |
98 | string $preHtmlContent = null |
99 | ): string { |
100 | $output = Html::openElement( 'div', [ 'class' => $className ] ); |
101 | if ( $preHtmlContent ) { |
102 | $output .= $preHtmlContent; |
103 | } |
104 | |
105 | $output .= Html::openElement( 'details' ); |
106 | $output .= Html::element( 'summary', [], $this->localizer->msg( $summaryMsgKey )->text() ); |
107 | $output .= Html::element( 'p', [], $this->localizer->msg( $descriptionMsgKey )->text() ); |
108 | $output .= $htmlContent; |
109 | $output .= Html::closeElement( 'details' ); |
110 | $output .= Html::closeElement( 'div' ); |
111 | |
112 | return $output; |
113 | } |
114 | |
115 | private function getHtmlForGroupErrors( |
116 | GroupSynchronizationResponse $groupErrorResponse, |
117 | Language $language, |
118 | string $wrapperClass |
119 | ): string { |
120 | $groupId = $groupErrorResponse->getGroupId(); |
121 | $output = Html::openElement( |
122 | 'details', |
123 | [ 'class' => "{$wrapperClass}__group_errors js-group-sync-group-errors" ] |
124 | ); |
125 | |
126 | $groupResolveAction = Html::linkButton( |
127 | $this->localizer->msg( 'translate-smg-group-action-resolve' )->text(), |
128 | [ |
129 | 'class' => "{$wrapperClass}__resolve-action js-group-sync-group-resolve", |
130 | 'href' => '#', |
131 | 'data-group-id' => $groupId, |
132 | ] |
133 | ); |
134 | |
135 | $output .= Html::rawElement( |
136 | 'summary', |
137 | [], |
138 | $groupId . ' ' . |
139 | Html::rawElement( |
140 | 'span', |
141 | [ 'class' => "{$wrapperClass}__sync-actions" ], |
142 | $this->localizer->msg( 'parentheses' ) |
143 | ->rawParams( $groupResolveAction )->escaped() |
144 | |
145 | ) |
146 | ); |
147 | |
148 | $errorMessages = $groupErrorResponse->getRemainingMessages(); |
149 | |
150 | $output .= Html::openElement( 'ol' ); |
151 | foreach ( $errorMessages as $message ) { |
152 | $output .= Html::rawElement( |
153 | 'li', |
154 | [ 'class' => "{$wrapperClass}__message-error js-group-sync-message-error" ], |
155 | $this->getErrorMessageHtml( $groupId, $message, $language, $wrapperClass ) |
156 | ); |
157 | } |
158 | $output .= Html::closeElement( 'ol' ); |
159 | |
160 | $output .= Html::closeElement( 'details' ); |
161 | |
162 | return $output; |
163 | } |
164 | |
165 | private function getErrorMessageHtml( |
166 | string $groupId, |
167 | MessageUpdateParameter $message, |
168 | Language $language, |
169 | string $wrapperClass |
170 | ): string { |
171 | $messageTitle = Title::newFromText( $message->getPageName() ); |
172 | $actions = []; |
173 | if ( $messageTitle->exists() ) { |
174 | $output = $this->linkRenderer->makeLink( $messageTitle, $message->getPageName() ); |
175 | $actions[] = $this->linkRenderer->makeLink( |
176 | $messageTitle, |
177 | $this->localizer->msg( 'translate-smg-group-message-action-history' )->text(), |
178 | [], |
179 | [ 'action' => 'history' ] |
180 | ); |
181 | } else { |
182 | $output = $this->linkRenderer->makeBrokenLink( $messageTitle, $message->getPageName() ); |
183 | } |
184 | |
185 | $actions[] = Html::linkButton( |
186 | $this->localizer->msg( 'translate-smg-group-action-resolve' )->text(), |
187 | [ |
188 | 'class' => "{$wrapperClass}__resolve-action js-group-sync-message-resolve", |
189 | 'href' => '#', |
190 | 'data-group-id' => $groupId, |
191 | 'data-msg-title' => $message->getPageName(), |
192 | ] |
193 | ); |
194 | |
195 | $output .= ' ' . Html::rawElement( |
196 | 'span', |
197 | [ 'class' => "{$wrapperClass}__sync-actions" ], |
198 | $this->localizer->msg( 'parentheses' ) |
199 | ->rawParams( $language->pipeList( $actions ) )->escaped() |
200 | ); |
201 | |
202 | $output .= $this->getMessageInfoHtml( $message, $language ); |
203 | |
204 | return $output; |
205 | } |
206 | |
207 | private function getMessageInfoHtml( MessageUpdateParameter $message, Language $language ): string { |
208 | $output = Html::openElement( 'dl' ); |
209 | |
210 | $tags = []; |
211 | if ( $message->isFuzzy() ) { |
212 | $tags[] = $this->localizer->msg( 'translate-smg-group-message-tag-outdated' )->text(); |
213 | } |
214 | |
215 | if ( $message->isRename() ) { |
216 | $tags[] = $this->localizer->msg( 'translate-smg-group-message-tag-rename' )->text(); |
217 | } |
218 | |
219 | if ( $tags ) { |
220 | $output .= $this->getMessagePropHtml( |
221 | $this->localizer->msg( 'translate-smg-group-message-tag-label' ) |
222 | ->numParams( count( $tags ) )->text(), |
223 | implode( $this->localizer->msg( 'pipe-separator' )->text(), $tags ) |
224 | ); |
225 | } |
226 | |
227 | $output .= $this->getMessagePropHtml( |
228 | $this->localizer->msg( 'translate-smg-group-message-message-content' )->text(), |
229 | $message->getContent() |
230 | ); |
231 | |
232 | if ( $message->isRename() ) { |
233 | $output .= $this->getMessagePropHtml( |
234 | $this->localizer->msg( 'translate-smg-group-message-message-target' )->text(), |
235 | $message->getTargetValue() |
236 | ); |
237 | |
238 | $output .= $this->getMessagePropHtml( |
239 | $this->localizer->msg( 'translate-smg-group-message-message-replacement' )->text(), |
240 | $message->getReplacementValue() |
241 | ); |
242 | |
243 | $otherLangs = $message->getOtherLangs(); |
244 | if ( $otherLangs ) { |
245 | $output .= $this->getMessagePropHtml( |
246 | $this->localizer->msg( 'translate-smg-group-message-message-other-langs' )->text(), |
247 | implode( |
248 | $this->localizer->msg( 'comma-separator' )->text(), |
249 | array_keys( $otherLangs ) |
250 | ) |
251 | ); |
252 | } |
253 | } |
254 | |
255 | $output .= Html::closeElement( 'dl' ); |
256 | return $output; |
257 | } |
258 | |
259 | private function getMessagePropHtml( string $label, string $value ): string { |
260 | return Html::element( 'dt', [], $label ) . Html::element( 'dd', [], $value ); |
261 | } |
262 | } |