Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
61.36% |
27 / 44 |
|
80.00% |
4 / 5 |
CRAP | |
0.00% |
0 / 1 |
CentralAuthUIService | |
61.36% |
27 / 44 |
|
80.00% |
4 / 5 |
22.75 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
formatHiddenLevel | |
100.00% |
4 / 4 |
|
100.00% |
1 / 1 |
4 | |||
prettyTimespan | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
3 | |||
showRenameLogExtract | |
0.00% |
0 / 17 |
|
0.00% |
0 / 1 |
2 | |||
processAntiSpoofConflicts | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\CentralAuth; |
4 | |
5 | use LogEventsList; |
6 | use MediaWiki\Context\IContextSource; |
7 | use MediaWiki\Extension\CentralAuth\User\CentralAuthUser; |
8 | use MediaWiki\HTMLForm\HTMLForm; |
9 | use MediaWiki\Title\TitleFactory; |
10 | use MessageLocalizer; |
11 | |
12 | /** |
13 | * Shared utilities for building UIs in CentralAuth |
14 | * |
15 | * @author Taavi "Majavah" Väänänen <hi@taavi.wtf> |
16 | */ |
17 | class CentralAuthUIService { |
18 | |
19 | private TitleFactory $titleFactory; |
20 | |
21 | public function __construct( TitleFactory $titleFactory ) { |
22 | $this->titleFactory = $titleFactory; |
23 | } |
24 | |
25 | /** |
26 | * Format a given CentralAuthUser::HIDDEN_* constant to a string. |
27 | * @param MessageLocalizer $localizer |
28 | * @param int $level one of the CentralAuthUser::HIDDEN_LEVEL_* constants |
29 | * @return string Already html escaped |
30 | */ |
31 | public function formatHiddenLevel( MessageLocalizer $localizer, int $level ): string { |
32 | switch ( $level ) { |
33 | case CentralAuthUser::HIDDEN_LEVEL_NONE: |
34 | return $localizer->msg( 'centralauth-admin-no' )->escaped(); |
35 | case CentralAuthUser::HIDDEN_LEVEL_LISTS: |
36 | return $localizer->msg( 'centralauth-admin-hidden-list' )->escaped(); |
37 | case CentralAuthUser::HIDDEN_LEVEL_SUPPRESSED: |
38 | return $localizer->msg( 'centralauth-admin-hidden-oversight' )->escaped(); |
39 | } |
40 | |
41 | return ''; |
42 | } |
43 | |
44 | /** |
45 | * Format a number of seconds into a human-readable timespan ("XX hours ago"). |
46 | * @param MessageLocalizer $localizer |
47 | * @param int $time in seconds |
48 | * @return string |
49 | */ |
50 | public function prettyTimespan( MessageLocalizer $localizer, int $time ): string { |
51 | // map all units for how many times they fit in the next unit |
52 | $units = [ |
53 | 'seconds' => 60, |
54 | 'minutes' => 60, |
55 | 'hours' => 24, |
56 | 'days' => 30.417, |
57 | 'months' => 12, |
58 | 'years' => 1 |
59 | ]; |
60 | |
61 | // Used messaged (to make sure that grep finds them): |
62 | // 'centralauth-seconds-ago', 'centralauth-minutes-ago', 'centralauth-hours-ago' |
63 | // 'centralauth-days-ago', 'centralauth-months-ago', 'centralauth-years-ago' |
64 | |
65 | // check each unit individually, to find a suitable unit to display |
66 | foreach ( $units as $unit => $chunk ) { |
67 | // if it's less than two times the size of the next unit, use this unit |
68 | // for example: 6 seconds uses seconds, 61 seconds uses seconds, 119 seconds uses seconds, |
69 | // but 121 seconds is detected that seconds isn't a useful unit anymore, and it goes to |
70 | // the next unit (minutes), and then it outputs 2 minutes (2 is under 2*60, it won't go to hours) |
71 | if ( $time < 2 * $chunk ) { |
72 | return $localizer->msg( "centralauth-$unit-ago" )->numParams( $time )->text(); |
73 | } |
74 | |
75 | // convert to the next unit, eg. seconds into minutes, minutes into hours, ... |
76 | $time = intval( $time / $chunk ); |
77 | } |
78 | |
79 | // if the timespan is so long that it's more than two times the size of the last unit, |
80 | // use the last unit (years) anyways |
81 | return $localizer->msg( "centralauth-years-ago" )->numParams( $time )->text(); |
82 | } |
83 | |
84 | /** |
85 | * Append an extract of the global rename log for the specific username. |
86 | * @param IContextSource $context |
87 | * @param string $name |
88 | */ |
89 | public function showRenameLogExtract( IContextSource $context, string $name ): void { |
90 | $caTitle = $this->titleFactory->makeTitle( NS_SPECIAL, 'CentralAuth/' . $name ); |
91 | |
92 | $logs = ''; |
93 | LogEventsList::showLogExtract( $logs, 'gblrename', $caTitle, '', [ |
94 | 'showIfEmpty' => true, |
95 | ] ); |
96 | |
97 | $formDescriptor = [ |
98 | 'logs' => [ |
99 | 'type' => 'info', |
100 | 'raw' => true, |
101 | 'default' => $logs, |
102 | ], |
103 | ]; |
104 | |
105 | $htmlForm = HTMLForm::factory( 'ooui', $formDescriptor, $context ); |
106 | $htmlForm->suppressDefaultSubmit() |
107 | ->setWrapperLegendMsg( 'centralauth-rename-progress-logs-fieldset' ) |
108 | ->prepareForm() |
109 | ->displayForm( false ); |
110 | } |
111 | |
112 | /** |
113 | * Format antispoof conflicts, change hidden ones to a generic text and link others to Special:CentralAuth. |
114 | * @param MessageLocalizer $localizer |
115 | * @param string $oldName User's old (current) name |
116 | * @param string[] $conflicts Conflicting usernames |
117 | * @return string[] Usernames formatted as wikitext, either saying that it's hidden or |
118 | * linking to Special:CentralAuth |
119 | */ |
120 | public function processAntiSpoofConflicts( |
121 | MessageLocalizer $localizer, |
122 | string $oldName, |
123 | array $conflicts |
124 | ): array { |
125 | $display = []; |
126 | |
127 | foreach ( $conflicts as $name ) { |
128 | if ( $name === $oldName ) { |
129 | // Not a conflict since the old usage will go away |
130 | continue; |
131 | } |
132 | $ca = CentralAuthUser::getInstanceByName( $name ); |
133 | if ( $ca->isHidden() ) { |
134 | $display[] = $localizer->msg( 'centralauth-rename-conflict-hidden' )->text(); |
135 | } else { |
136 | $display[] = "[[Special:CentralAuth/$name|$name]]"; |
137 | } |
138 | } |
139 | |
140 | return $display; |
141 | } |
142 | } |