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