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