Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
61.36% covered (warning)
61.36%
27 / 44
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
CentralAuthUIService
61.36% covered (warning)
61.36%
27 / 44
80.00% covered (warning)
80.00%
4 / 5
22.75
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 formatHiddenLevel
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
4
 prettyTimespan
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
1 / 1
3
 showRenameLogExtract
0.00% covered (danger)
0.00%
0 / 17
0.00% covered (danger)
0.00%
0 / 1
2
 processAntiSpoofConflicts
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
1 / 1
4
1<?php
2
3namespace MediaWiki\Extension\CentralAuth;
4
5use LogEventsList;
6use MediaWiki\Context\IContextSource;
7use MediaWiki\Extension\CentralAuth\User\CentralAuthUser;
8use MediaWiki\HTMLForm\HTMLForm;
9use MediaWiki\Title\TitleFactory;
10use MessageLocalizer;
11
12/**
13 * Shared utilities for building UIs in CentralAuth
14 *
15 * @author Taavi "Majavah" Väänänen <hi@taavi.wtf>
16 */
17class 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}