Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
94.74% covered (success)
94.74%
18 / 19
83.33% covered (warning)
83.33%
5 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
EventTimeFormatter
94.74% covered (success)
94.74%
18 / 19
83.33% covered (warning)
83.33%
5 / 6
9.01
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 formatStart
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 formatEnd
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 formatTimeInternal
100.00% covered (success)
100.00%
7 / 7
100.00% covered (success)
100.00%
1 / 1
2
 formatTimezone
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
2
 getTimeCorrection
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare( strict_types=1 );
4
5namespace MediaWiki\Extension\CampaignEvents\Time;
6
7use Language;
8use MediaWiki\Extension\CampaignEvents\Event\EventRegistration;
9use MediaWiki\Extension\CampaignEvents\Utils;
10use MediaWiki\User\Options\UserOptionsLookup;
11use MediaWiki\User\UserIdentity;
12use MediaWiki\User\UserTimeCorrection;
13
14/**
15 * This service formats the time of an event according to the event type, in a given language and for a given user.
16 * The timezone used for the return value can be obtained separately.
17 */
18class EventTimeFormatter {
19    public const SERVICE_NAME = 'CampaignEventsEventTimeFormatter';
20
21    private UserOptionsLookup $userOptionsLookup;
22
23    private const FORMAT_START = 'start';
24    private const FORMAT_END = 'end';
25
26    /**
27     * @param UserOptionsLookup $userOptionsLookup
28     */
29    public function __construct( UserOptionsLookup $userOptionsLookup ) {
30        $this->userOptionsLookup = $userOptionsLookup;
31    }
32
33    /**
34     * @param EventRegistration $event
35     * @param Language $language
36     * @param UserIdentity $user
37     * @return FormattedTime
38     */
39    public function formatStart(
40        EventRegistration $event,
41        Language $language,
42        UserIdentity $user
43    ): FormattedTime {
44        return $this->formatTimeInternal( self::FORMAT_START, $event, $language, $user );
45    }
46
47    /**
48     * @param EventRegistration $event
49     * @param Language $language
50     * @param UserIdentity $user
51     * @return FormattedTime
52     */
53    public function formatEnd(
54        EventRegistration $event,
55        Language $language,
56        UserIdentity $user
57    ): FormattedTime {
58        return $this->formatTimeInternal( self::FORMAT_END, $event, $language, $user );
59    }
60
61    /**
62     * @param string $type self::FORMAT_START or self::FORMAT_END
63     * @param EventRegistration $event
64     * @param Language $language
65     * @param UserIdentity $user
66     * @return FormattedTime
67     */
68    private function formatTimeInternal(
69        string $type,
70        EventRegistration $event,
71        Language $language,
72        UserIdentity $user
73    ): FormattedTime {
74        $formatOptions = [ 'timecorrection' => $this->getTimeCorrection( $event, $user )->toString() ];
75        $utcTimestamp = $type === self::FORMAT_START ? $event->getStartUTCTimestamp() : $event->getEndUTCTimestamp();
76        return new FormattedTime(
77            $language->userTime( $utcTimestamp, $user, $formatOptions ),
78            $language->userDate( $utcTimestamp, $user, $formatOptions ),
79            $language->userTimeAndDate( $utcTimestamp, $user, $formatOptions )
80        );
81    }
82
83    /**
84     * @param EventRegistration $eventRegistration
85     * @param UserIdentity $user
86     * @return string
87     */
88    public function formatTimezone( EventRegistration $eventRegistration, UserIdentity $user ): string {
89        $userTimeCorrection = $this->getTimeCorrection( $eventRegistration, $user );
90        $tzObj = $userTimeCorrection->getTimeZone();
91        if ( $tzObj ) {
92            return $tzObj->getName();
93        }
94        return UserTimeCorrection::formatTimezoneOffset( $userTimeCorrection->getTimeOffset() );
95    }
96
97    /**
98     * Returns the time correction that should be used when formatting time, date, and timezone.
99     * This uses the event timezone for in-person events, and the user preference for online and hybrid events,
100     * see T316688.
101     *
102     * @param EventRegistration $event
103     * @param UserIdentity $user
104     * @return UserTimeCorrection
105     */
106    private function getTimeCorrection( EventRegistration $event, UserIdentity $user ): UserTimeCorrection {
107        if ( $event->getMeetingType() === EventRegistration::MEETING_TYPE_IN_PERSON ) {
108            return Utils::timezoneToUserTimeCorrection( $event->getTimezone() );
109        }
110        $timeCorrectionPref = $this->userOptionsLookup->getOption( $user, 'timecorrection' ) ?? '';
111        return new UserTimeCorrection( $timeCorrectionPref );
112    }
113}