Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
93.85% covered (success)
93.85%
61 / 65
92.00% covered (success)
92.00%
23 / 25
CRAP
0.00% covered (danger)
0.00%
0 / 1
EventRegistration
93.85% covered (success)
93.85%
61 / 65
92.00% covered (success)
92.00%
23 / 25
25.15
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
1 / 1
1
 getID
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getName
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getPage
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getChatURL
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getWikis
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTopics
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTrackingTools
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStatus
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getTimezone
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStartLocalTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getStartUTCTimestamp
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 getEndLocalTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getEndUTCTimestamp
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
1
 isPast
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMeetingType
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMeetingURL
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMeetingCountry
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getMeetingAddress
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getParticipantQuestions
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getCreationTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getLastEditTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getDeletionTimestamp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 isOnLocalWiki
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2
3declare( strict_types=1 );
4
5namespace MediaWiki\Extension\CampaignEvents\Event;
6
7use DateTime;
8use DateTimeZone;
9use MediaWiki\DAO\WikiAwareEntity;
10use MediaWiki\Extension\CampaignEvents\MWEntity\ICampaignsPage;
11use MediaWiki\Extension\CampaignEvents\TrackingTool\TrackingToolAssociation;
12use MediaWiki\Utils\MWTimestamp;
13use Wikimedia\Assert\Assert;
14
15/**
16 * Immutable value object that represents an abstract registration, i.e. one that may not exist in the database.
17 */
18class EventRegistration {
19    public const STATUS_OPEN = 'open';
20    public const STATUS_CLOSED = 'closed';
21    public const VALID_STATUSES = [ self::STATUS_OPEN, self::STATUS_CLOSED ];
22
23    public const TYPE_GENERIC = 'generic';
24    public const VALID_TYPES = [ self::TYPE_GENERIC ];
25
26    public const ALL_WIKIS = true;
27
28    public const MEETING_TYPE_ONLINE = 1 << 0;
29    public const MEETING_TYPE_IN_PERSON = 1 << 1;
30    public const MEETING_TYPE_ONLINE_AND_IN_PERSON = self::MEETING_TYPE_ONLINE | self::MEETING_TYPE_IN_PERSON;
31    public const VALID_MEETING_TYPES = [
32        self::MEETING_TYPE_ONLINE,
33        self::MEETING_TYPE_IN_PERSON,
34        self::MEETING_TYPE_ONLINE_AND_IN_PERSON
35    ];
36
37    private ?int $id;
38    /**
39     * @var string
40     * @todo Is this necessary?
41     */
42    private string $name;
43    private ICampaignsPage $page;
44    private ?string $chatURL;
45    /** @var string[]|true List of wikis, or self::ALL_WIKIS */
46    private $wikis;
47    /** @var string[] */
48    private array $topics;
49    /**
50     * @var TrackingToolAssociation[]
51     * @phan-var list<TrackingToolAssociation>
52     */
53    private array $trackingTools;
54    /** @var string One of the STATUS_* constants */
55    private string $status;
56    private DateTimeZone $timezone;
57    private string $startLocalTimestamp;
58    private string $endLocalTimestamp;
59    /** @var string One of the TYPE_* constants */
60    private string $type;
61    /** @var int One of the MEETING_TYPE_* constants */
62    private int $meetingType;
63    private ?string $meetingURL;
64    private ?string $meetingCountry;
65    private ?string $meetingAddress;
66    /** @var int[] Array of database IDs */
67    private array $participantQuestions;
68    private ?string $creationTimestamp;
69    private ?string $lastEditTimestamp;
70    private ?string $deletionTimestamp;
71
72    /**
73     * @param int|null $id
74     * @param string $name
75     * @param ICampaignsPage $page
76     * @param string|null $chatURL
77     * @param string[]|true $wikis A list of wiki IDs, or {@see self::ALL_WIKIS}.
78     * @param string[] $topics
79     * @param TrackingToolAssociation[] $trackingTools
80     * @phan-param list<TrackingToolAssociation> $trackingTools
81     * @param string $status
82     * @param DateTimeZone $timezone
83     * @param string $startLocalTimestamp TS_MW timestamp
84     * @param string $endLocalTimestamp TS_MW timestamp
85     * @param string $type
86     * @param int $meetingType
87     * @param string|null $meetingURL
88     * @param string|null $meetingCountry
89     * @param string|null $meetingAddress
90     * @param array $participantQuestions
91     * @param string|null $creationTimestamp UNIX timestamp
92     * @param string|null $lastEditTimestamp UNIX timestamp
93     * @param string|null $deletionTimestamp UNIX timestamp
94     */
95    public function __construct(
96        ?int $id,
97        string $name,
98        ICampaignsPage $page,
99        ?string $chatURL,
100        $wikis,
101        array $topics,
102        array $trackingTools,
103        string $status,
104        DateTimeZone $timezone,
105        string $startLocalTimestamp,
106        string $endLocalTimestamp,
107        string $type,
108        int $meetingType,
109        ?string $meetingURL,
110        ?string $meetingCountry,
111        ?string $meetingAddress,
112        array $participantQuestions,
113        ?string $creationTimestamp,
114        ?string $lastEditTimestamp,
115        ?string $deletionTimestamp
116    ) {
117        Assert::parameter(
118            MWTimestamp::convert( TS_MW, $startLocalTimestamp ) === $startLocalTimestamp,
119            '$startLocalTimestamp',
120            'Should be in TS_MW format.'
121        );
122        Assert::parameter(
123            MWTimestamp::convert( TS_MW, $endLocalTimestamp ) === $endLocalTimestamp,
124            '$endLocalTimestamp',
125            'Should be in TS_MW format.'
126        );
127        Assert::parameter(
128            count( $trackingTools ) <= 1,
129            '$trackingTools',
130            'Should not have more than one tracking tool'
131        );
132        $this->id = $id;
133        $this->name = $name;
134        $this->page = $page;
135        $this->chatURL = $chatURL;
136        $this->wikis = $wikis;
137        $this->trackingTools = $trackingTools;
138        $this->status = $status;
139        $this->timezone = $timezone;
140        $this->startLocalTimestamp = $startLocalTimestamp;
141        $this->endLocalTimestamp = $endLocalTimestamp;
142        $this->type = $type;
143        $this->meetingType = $meetingType;
144        $this->meetingURL = $meetingURL;
145        $this->meetingCountry = $meetingCountry;
146        $this->meetingAddress = $meetingAddress;
147        $this->participantQuestions = $participantQuestions;
148        $this->creationTimestamp = $creationTimestamp;
149        $this->lastEditTimestamp = $lastEditTimestamp;
150        $this->deletionTimestamp = $deletionTimestamp;
151        $this->topics = $topics;
152    }
153
154    /**
155     * @return int|null
156     */
157    public function getID(): ?int {
158        return $this->id;
159    }
160
161    /**
162     * @return string
163     */
164    public function getName(): string {
165        return $this->name;
166    }
167
168    /**
169     * @return ICampaignsPage
170     */
171    public function getPage(): ICampaignsPage {
172        return $this->page;
173    }
174
175    /**
176     * @return string|null
177     */
178    public function getChatURL(): ?string {
179        return $this->chatURL;
180    }
181
182    /**
183     * @return string[]|true A list of wiki IDs, or {@see self::ALL_WIKIS}.
184     */
185    public function getWikis() {
186        return $this->wikis;
187    }
188
189    /**
190     * @return string[] A list of topics.
191     */
192    public function getTopics(): array {
193        return $this->topics;
194    }
195
196    /**
197     * @return TrackingToolAssociation[]
198     * @phan-return list<TrackingToolAssociation>
199     */
200    public function getTrackingTools(): array {
201        return $this->trackingTools;
202    }
203
204    /**
205     * @return string
206     */
207    public function getStatus(): string {
208        return $this->status;
209    }
210
211    /**
212     * @return DateTimeZone
213     */
214    public function getTimezone(): DateTimeZone {
215        return $this->timezone;
216    }
217
218    /**
219     * @return string Timestamp in the TS_MW format
220     */
221    public function getStartLocalTimestamp(): string {
222        return $this->startLocalTimestamp;
223    }
224
225    /**
226     * @return string Timestamp in the TS_MW format
227     */
228    public function getStartUTCTimestamp(): string {
229        $localDateTime = new DateTime( $this->startLocalTimestamp, $this->timezone );
230        $utcStartTime = $localDateTime->setTimezone( new DateTimeZone( 'UTC' ) )->getTimestamp();
231        return wfTimestamp( TS_MW, $utcStartTime );
232    }
233
234    /**
235     * @return string Timestamp in TS_MW format
236     */
237    public function getEndLocalTimestamp(): string {
238        return $this->endLocalTimestamp;
239    }
240
241    /**
242     * @return string Timestamp in the TS_MW format
243     */
244    public function getEndUTCTimestamp(): string {
245        $localDateTime = new DateTime( $this->endLocalTimestamp, $this->timezone );
246        $utcEndTime = $localDateTime->setTimezone( new DateTimeZone( 'UTC' ) )->getTimestamp();
247        return wfTimestamp( TS_MW, $utcEndTime );
248    }
249
250    /**
251     * @return bool
252     */
253    public function isPast(): bool {
254        return wfTimestamp( TS_UNIX, $this->getEndUTCTimestamp() ) < MWTimestamp::now( TS_UNIX );
255    }
256
257    /**
258     * @return string
259     */
260    public function getType(): string {
261        return $this->type;
262    }
263
264    /**
265     * @return int
266     */
267    public function getMeetingType(): int {
268        return $this->meetingType;
269    }
270
271    /**
272     * @return string|null
273     */
274    public function getMeetingURL(): ?string {
275        return $this->meetingURL;
276    }
277
278    /**
279     * @return string|null
280     */
281    public function getMeetingCountry(): ?string {
282        return $this->meetingCountry;
283    }
284
285    /**
286     * @return string|null
287     */
288    public function getMeetingAddress(): ?string {
289        return $this->meetingAddress;
290    }
291
292    /**
293     * @return int[]
294     */
295    public function getParticipantQuestions(): array {
296        return $this->participantQuestions;
297    }
298
299    /**
300     * @return string|null
301     */
302    public function getCreationTimestamp(): ?string {
303        return $this->creationTimestamp;
304    }
305
306    /**
307     * @return string|null
308     */
309    public function getLastEditTimestamp(): ?string {
310        return $this->lastEditTimestamp;
311    }
312
313    /**
314     * @return string|null
315     */
316    public function getDeletionTimestamp(): ?string {
317        return $this->deletionTimestamp;
318    }
319
320    /**
321     * @return bool
322     */
323    public function isOnLocalWiki(): bool {
324        $eventPage = $this->getPage();
325        $wikiID = $eventPage->getWikiId();
326        return $wikiID === WikiAwareEntity::LOCAL;
327    }
328}