Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 153 |
|
0.00% |
0 / 13 |
CRAP | |
0.00% |
0 / 1 |
FlaggedRevsXML | |
0.00% |
0 / 153 |
|
0.00% |
0 / 13 |
1332 | |
0.00% |
0 / 1 |
getNamespaceMenu | |
0.00% |
0 / 16 |
|
0.00% |
0 / 1 |
56 | |||
getDefaultFilterMenu | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
getRestrictionFilterMenu | |
0.00% |
0 / 15 |
|
0.00% |
0 / 1 |
30 | |||
addTagRatings | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
6 | |||
prettyRatingBox | |
0.00% |
0 / 31 |
|
0.00% |
0 / 1 |
132 | |||
ratingArrow | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
diffToggle | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
2 | |||
draftStatusIcon | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
stableStatusIcon | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
lockStatusIcon | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
12 | |||
pendingEditNotice | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
pendingEditNoticeMessage | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
stabilityLogExcerpt | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | use MediaWiki\Html\Html; |
4 | use MediaWiki\MediaWikiServices; |
5 | use MediaWiki\Title\Title; |
6 | |
7 | /** |
8 | * Class containing utility XML functions for a FlaggedRevs. |
9 | * Includes functions for selectors, icons, notices, CSS, and form aspects. |
10 | */ |
11 | class FlaggedRevsXML { |
12 | |
13 | /** |
14 | * Get a selector of reviewable namespaces |
15 | * @param int|null $selected namespace selected |
16 | * @param string|null $all Value of an item denoting all namespaces, or null to omit |
17 | */ |
18 | public static function getNamespaceMenu( ?int $selected = null, ?string $all = null ): string { |
19 | $s = "<label for='namespace'>" . wfMessage( 'namespace' )->escaped() . "</label>"; |
20 | # No namespace selected; let exact match work without hitting Main |
21 | $selected ??= ''; |
22 | $s .= "\n<select id='namespace' name='namespace' class='namespaceselector'>\n"; |
23 | $arr = MediaWikiServices::getInstance()->getContentLanguage()->getFormattedNamespaces(); |
24 | if ( $all !== null ) { |
25 | $arr = [ $all => wfMessage( 'namespacesall' )->text() ] + $arr; // should be first |
26 | } |
27 | foreach ( $arr as $index => $name ) { |
28 | # Content pages only (except 'all') |
29 | if ( $index !== $all && !FlaggedRevs::isReviewNamespace( $index ) ) { |
30 | continue; |
31 | } |
32 | $name = $index !== 0 ? $name : wfMessage( 'blanknamespace' )->text(); |
33 | if ( $index === $selected ) { |
34 | $s .= "\t" . Html::element( 'option', [ 'value' => $index, |
35 | "selected" => "selected" ], $name ) . "\n"; |
36 | } else { |
37 | $s .= "\t" . Html::element( 'option', [ 'value' => $index ], $name ) . "\n"; |
38 | } |
39 | } |
40 | $s .= "</select>\n"; |
41 | return $s; |
42 | } |
43 | |
44 | /** |
45 | * Get a <select> of default page version (stable or draft). Used for filters. |
46 | * @param int|null $selected (0=draft, 1=stable, null=either ) |
47 | */ |
48 | public static function getDefaultFilterMenu( ?int $selected = null ): string { |
49 | $s = Xml::option( wfMessage( 'revreview-def-all' )->text(), '', ( $selected ?? '' ) === '' ); |
50 | $s .= Xml::option( wfMessage( 'revreview-def-stable' )->text(), '1', $selected === 1 ); |
51 | $s .= Xml::option( wfMessage( 'revreview-def-draft' )->text(), '0', $selected === 0 ); |
52 | return Xml::label( wfMessage( 'revreview-defaultfilter' )->text(), 'wpStable' ) . "\n" . |
53 | Html::rawElement( 'select', [ 'name' => 'stable', 'id' => 'wpStable' ], $s ) . "\n"; |
54 | } |
55 | |
56 | /** |
57 | * Get a <select> of options of 'autoreview' restriction levels. Used for filters. |
58 | * @param string|null $selected (null or empty string for "any", 'none' for none) |
59 | */ |
60 | public static function getRestrictionFilterMenu( ?string $selected = '' ): string { |
61 | if ( $selected === null ) { |
62 | $selected = ''; // "all" |
63 | } |
64 | $s = Xml::label( wfMessage( 'revreview-restrictfilter' )->text(), 'wpRestriction' ) . "\n"; |
65 | $s .= Html::openElement( 'select', |
66 | [ 'name' => 'restriction', 'id' => 'wpRestriction' ] ); |
67 | $s .= Xml::option( wfMessage( 'revreview-restriction-any' )->text(), '', $selected == '' ); |
68 | if ( !FlaggedRevs::useProtectionLevels() ) { |
69 | # All "protected" pages have a protection level, not "none" |
70 | $s .= Xml::option( wfMessage( 'revreview-restriction-none' )->text(), |
71 | 'none', $selected == 'none' ); |
72 | } |
73 | foreach ( FlaggedRevs::getRestrictionLevels() as $perm ) { |
74 | // Give grep a chance to find the usages: |
75 | // revreview-restriction-any, revreview-restriction-none |
76 | $key = "revreview-restriction-$perm"; |
77 | $msg = wfMessage( $key )->isDisabled() ? $perm : wfMessage( $key )->text(); |
78 | $s .= Xml::option( $msg, $perm, $selected == $perm ); |
79 | } |
80 | $s .= Html::closeElement( 'select' ) . "\n"; |
81 | return $s; |
82 | } |
83 | |
84 | /** |
85 | * Generates a review box/tag |
86 | * @param array<string,int> $flags |
87 | */ |
88 | public static function addTagRatings( array $flags ): string { |
89 | $tag = Html::openElement( |
90 | 'table', |
91 | [ |
92 | 'id' => 'mw-fr-revisionratings-box', |
93 | 'style' => 'margin: auto;', |
94 | 'class' => 'flaggedrevs-color-1', |
95 | 'cellpadding' => '0', |
96 | ] |
97 | ); |
98 | $quality = FlaggedRevs::getTagName(); |
99 | |
100 | if ( !FlaggedRevs::useOnlyIfProtected() ) { |
101 | // Give grep a chance to find the usages: |
102 | // revreview-accuracy-0, revreview-accuracy-1, revreview-accuracy-2, |
103 | // revreview-accuracy-3, revreview-accuracy-4 |
104 | $level = $flags[$quality] ?? 0; |
105 | $encValueText = wfMessage( "revreview-$quality-$level" )->escaped(); |
106 | |
107 | $levelmarker = $level * 20 + 20; |
108 | // Give grep a chance to find the usages: |
109 | // revreview-accuracy |
110 | $tag .= "<tr><td class='fr-text' style='vertical-align: middle;'>" . |
111 | wfMessage( "revreview-$quality" )->escaped() . |
112 | "</td><td class='fr-value$levelmarker' style='vertical-align: middle;'>" . |
113 | $encValueText . "</td></tr>\n"; |
114 | $tag .= Html::closeElement( 'table' ); |
115 | } |
116 | return $tag; |
117 | } |
118 | |
119 | /** |
120 | * Generates a review box using a table using FlaggedRevsXML::addTagRatings() |
121 | * @param FlaggedRevision $frev the reviewed version |
122 | * @param string $shtml Short message HTML |
123 | * @param int $revsSince revisions since review |
124 | * @param string $type (stable/draft/oldstable) |
125 | * @param bool $synced does stable=current and this is one of them? |
126 | */ |
127 | public static function prettyRatingBox( |
128 | FlaggedRevision $frev, |
129 | string $shtml, |
130 | int $revsSince, |
131 | string $type = 'oldstable', |
132 | bool $synced = false |
133 | ): string { |
134 | global $wgLang; |
135 | $flags = $frev->getTags(); |
136 | $time = $wgLang->date( $frev->getTimestamp(), true ); |
137 | # Construct some tagging |
138 | if ( $synced && ( $type == 'stable' || $type == 'draft' ) ) { |
139 | $msg = 'revreview-basic-same'; |
140 | $html = wfMessage( $msg, $frev->getRevId(), $time )->numParams( $revsSince )->parse(); |
141 | } elseif ( $type == 'oldstable' ) { |
142 | $msg = 'revreview-basic-old'; |
143 | $html = wfMessage( $msg, $frev->getRevId(), $time )->parse(); |
144 | } else { |
145 | $msg = $type === 'stable' ? 'revreview-basic' : 'revreview-newest-basic'; |
146 | # For searching: uses messages 'revreview-basic-i', 'revreview-newest-basic-i' |
147 | $msg .= !$revsSince ? '-i' : ''; |
148 | $html = wfMessage( $msg, $frev->getRevId(), $time )->numParams( $revsSince )->parse(); |
149 | } |
150 | # Make fancy box... |
151 | $box = '<div class="flaggedrevs_short_basic">'; |
152 | $box .= $shtml . self::ratingArrow(); |
153 | $box .= "</div>\n"; |
154 | // For rel-absolute child div (the fly-out) |
155 | $box .= '<div id="mw-fr-revisiondetails-wrapper" style="position:relative;">'; |
156 | $box .= Html::openElement( |
157 | 'div', |
158 | [ |
159 | 'id' => 'mw-fr-revisiondetails', |
160 | 'class' => 'flaggedrevs_short_details', |
161 | 'style' => 'display:none' |
162 | ] |
163 | ); |
164 | $box .= $html; // details text |
165 | # Add any rating tags as needed... |
166 | if ( $flags && !FlaggedRevs::binaryFlagging() ) { |
167 | # Don't show the ratings on draft views |
168 | if ( $type == 'stable' || $type == 'oldstable' ) { |
169 | $box .= '<p>' . self::addTagRatings( $flags ) . '</p>'; |
170 | } |
171 | } |
172 | $box .= Html::closeElement( 'div' ) . "\n"; |
173 | $box .= "</div>\n"; |
174 | return $box; |
175 | } |
176 | |
177 | /** |
178 | * Generates JS toggle arrow icon |
179 | */ |
180 | private static function ratingArrow(): string { |
181 | return ( new OOUI\IndicatorWidget( |
182 | [ |
183 | 'indicator' => 'down', |
184 | 'classes' => [ 'fr-toggle-arrow' ], |
185 | 'id' => 'mw-fr-revisiontoggle', |
186 | 'title' => wfMessage( 'revreview-toggle-title' )->text(), |
187 | ] |
188 | ) )->toString(); |
189 | } |
190 | |
191 | /** |
192 | * Generates the "(show/hide)" diff toggle. With JS disabled, it functions as a link to the diff. |
193 | * @param Title $title |
194 | * @param int $fromrev |
195 | * @param int $torev |
196 | * @param string|null $multiNotice Message about intermediate revisions |
197 | */ |
198 | public static function diffToggle( Title $title, int $fromrev, int $torev, string $multiNotice = null ): string { |
199 | // Construct a link to the diff |
200 | $href = $title->getFullURL( [ 'diff' => $torev, 'oldid' => $fromrev ] ); |
201 | |
202 | $toggle = Html::element( 'a', [ |
203 | 'class' => 'fr-toggle-text', |
204 | 'title' => wfMessage( 'revreview-diff-toggle-title' )->text(), |
205 | 'href' => $href, |
206 | 'data-mw-fromrev' => $fromrev, |
207 | 'data-mw-torev' => $torev, |
208 | 'data-mw-multinotice' => $multiNotice, |
209 | ], wfMessage( 'revreview-diff-toggle-show' )->text() ); |
210 | |
211 | return '<span id="mw-fr-difftoggle">' . |
212 | wfMessage( 'parentheses' )->rawParams( $toggle )->escaped() . '</span>'; |
213 | } |
214 | |
215 | /** |
216 | * Creates CSS draft page icon |
217 | */ |
218 | public static function draftStatusIcon(): string { |
219 | $encTitle = wfMessage( 'revreview-draft-title' )->text(); |
220 | return ( new OOUI\IconWidget( |
221 | [ |
222 | 'icon' => 'block', |
223 | 'classes' => [ 'flaggedrevs-icon' ], |
224 | 'title' => $encTitle, |
225 | ] |
226 | ) )->toString(); |
227 | } |
228 | |
229 | /** |
230 | * Creates CSS stable page icon |
231 | */ |
232 | public static function stableStatusIcon(): string { |
233 | $encTitle = wfMessage( 'revreview-basic-title' )->text(); |
234 | return ( new OOUI\IconWidget( |
235 | [ |
236 | 'icon' => 'eye', |
237 | 'classes' => [ 'flaggedrevs-icon' ], |
238 | 'title' => $encTitle, |
239 | ] |
240 | ) )->toString(); |
241 | } |
242 | |
243 | /** |
244 | * Creates CSS lock icon if page is locked/unlocked |
245 | */ |
246 | public static function lockStatusIcon( FlaggableWikiPage $flaggedArticle ): string { |
247 | if ( $flaggedArticle->isPageLocked() ) { |
248 | $encTitle = wfMessage( 'revreview-locked-title' )->text(); |
249 | $icon = 'articleSearch'; |
250 | } elseif ( $flaggedArticle->isPageUnlocked() ) { |
251 | $encTitle = wfMessage( 'revreview-unlocked-title' )->text(); |
252 | $icon = 'articleCheck'; |
253 | } else { |
254 | return ''; |
255 | } |
256 | return ( new OOUI\IconWidget( |
257 | [ |
258 | 'icon' => $icon, |
259 | 'classes' => [ 'flaggedrevs-icon' ], |
260 | 'title' => $encTitle, |
261 | ] |
262 | ) )->toString(); |
263 | } |
264 | |
265 | /** |
266 | * Creates "stable rev reviewed on"/"x pending edits" message |
267 | */ |
268 | public static function pendingEditNotice( FlaggedRevision $frev, int $revsSince ): string { |
269 | $msg = self::pendingEditNoticeMessage( $frev, $revsSince ); |
270 | return $msg->parse(); |
271 | } |
272 | |
273 | /** |
274 | * Same as pendingEditNotice(), but returns a Message object. |
275 | */ |
276 | public static function pendingEditNoticeMessage( FlaggedRevision $frev, int $revsSince ): Message { |
277 | global $wgLang; |
278 | $time = $wgLang->date( $frev->getTimestamp(), true ); |
279 | # Add message text for pending edits |
280 | return wfMessage( 'revreview-pending-basic', $frev->getRevId(), $time )->numParams( $revsSince ); |
281 | } |
282 | |
283 | /** |
284 | * Creates a stability log excerpt |
285 | */ |
286 | public static function stabilityLogExcerpt( Title $title ): string { |
287 | $logHtml = ''; |
288 | $params = [ |
289 | 'lim' => 1, |
290 | 'flags' => LogEventsList::NO_EXTRA_USER_LINKS |
291 | ]; |
292 | LogEventsList::showLogExtract( $logHtml, 'stable', |
293 | $title->getPrefixedText(), '', $params ); |
294 | return Html::rawElement( |
295 | 'div', |
296 | [ 'id' => 'mw-fr-logexcerpt' ], |
297 | $logHtml |
298 | ); |
299 | } |
300 | |
301 | } |