Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 159 |
|
0.00% |
0 / 12 |
CRAP | |
0.00% |
0 / 1 |
RegistrationNotificationPresentationModel | |
0.00% |
0 / 159 |
|
0.00% |
0 / 12 |
600 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
2 | |||
canRender | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
12 | |||
getIconType | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSubjectMessage | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
getHeaderMessage | |
0.00% |
0 / 21 |
|
0.00% |
0 / 1 |
6 | |||
getBodyMessage | |
0.00% |
0 / 14 |
|
0.00% |
0 / 1 |
2 | |||
getDatesBodySection | |
0.00% |
0 / 30 |
|
0.00% |
0 / 1 |
2 | |||
getTypeBodySection | |
0.00% |
0 / 31 |
|
0.00% |
0 / 1 |
42 | |||
gerOrganizersBodySection | |
0.00% |
0 / 30 |
|
0.00% |
0 / 1 |
20 | |||
getPrimaryLink | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
getSecondaryLinks | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 | |||
makeLink | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | declare( strict_types=1 ); |
3 | |
4 | namespace MediaWiki\Extension\CampaignEvents\Notifications; |
5 | |
6 | use EchoEvent; |
7 | use Language; |
8 | use MediaWiki\Extension\CampaignEvents\CampaignEventsServices; |
9 | use MediaWiki\Extension\CampaignEvents\Event\EventRegistration; |
10 | use MediaWiki\Extension\CampaignEvents\Event\ExistingEventRegistration; |
11 | use MediaWiki\Extension\CampaignEvents\MWEntity\CentralUserNotFoundException; |
12 | use MediaWiki\Extension\CampaignEvents\MWEntity\HiddenCentralUserException; |
13 | use MediaWiki\Extension\CampaignEvents\MWEntity\PageURLResolver; |
14 | use MediaWiki\Extension\CampaignEvents\MWEntity\UserLinker; |
15 | use MediaWiki\Extension\CampaignEvents\Organizers\OrganizersStore; |
16 | use MediaWiki\Extension\CampaignEvents\Special\SpecialEventDetails; |
17 | use MediaWiki\Extension\CampaignEvents\Time\EventTimeFormatter; |
18 | use MediaWiki\Extension\Notifications\Formatters\EchoEventPresentationModel; |
19 | use MediaWiki\Html\Html; |
20 | use MediaWiki\Language\RawMessage; |
21 | use MediaWiki\SpecialPage\SpecialPage; |
22 | use MediaWiki\User\User; |
23 | use Message; |
24 | |
25 | class RegistrationNotificationPresentationModel extends EchoEventPresentationModel { |
26 | public const NOTIFICATION_NAME = 'campaign-events-notification-registration-confirmation'; |
27 | public const ICON_NAME = 'campaignevents-registration'; |
28 | |
29 | private const ORGANIZERS_LIMIT = 4; |
30 | |
31 | private ExistingEventRegistration $eventRegistration; |
32 | private PageURLResolver $pageUrlResolver; |
33 | private EventTimeFormatter $eventTimeFormatter; |
34 | private OrganizersStore $organizersStore; |
35 | private UserLinker $userLinker; |
36 | |
37 | /** |
38 | * @param EchoEvent $event |
39 | * @param Language $language |
40 | * @param User $user Only used for permissions checking and GENDER |
41 | * @param string $distributionType |
42 | */ |
43 | protected function __construct( |
44 | EchoEvent $event, |
45 | Language $language, |
46 | User $user, |
47 | $distributionType |
48 | ) { |
49 | parent::__construct( $event, $language, $user, $distributionType ); |
50 | $eventLookup = CampaignEventsServices::getEventLookup(); |
51 | $eventID = $this->event->getExtraParam( 'event-id' ); |
52 | $this->eventRegistration = $eventLookup->getEventByID( $eventID ); |
53 | $this->pageUrlResolver = CampaignEventsServices::getPageURLResolver(); |
54 | $this->eventTimeFormatter = CampaignEventsServices::getEventTimeFormatter(); |
55 | $this->organizersStore = CampaignEventsServices::getOrganizersStore(); |
56 | $this->userLinker = CampaignEventsServices::getUserLinker(); |
57 | } |
58 | |
59 | /** |
60 | * @inheritDoc |
61 | */ |
62 | public function canRender(): bool { |
63 | if ( $this->getDistributionType() !== 'email' ) { |
64 | return false; |
65 | } |
66 | |
67 | if ( $this->eventRegistration->getDeletionTimestamp() !== null ) { |
68 | return false; |
69 | } |
70 | return true; |
71 | } |
72 | |
73 | /** |
74 | * @inheritDoc |
75 | */ |
76 | public function getIconType(): string { |
77 | return self::ICON_NAME; |
78 | } |
79 | |
80 | /** |
81 | * @inheritDoc |
82 | */ |
83 | public function getSubjectMessage(): Message { |
84 | return $this->msg( 'campaignevents-notification-registration-subject' ) |
85 | ->params( $this->eventRegistration->getName() ); |
86 | } |
87 | |
88 | /** |
89 | * @inheritDoc |
90 | */ |
91 | public function getHeaderMessage() { |
92 | $eventPageLink = $this->makeLink( |
93 | $this->pageUrlResolver->getFullUrl( $this->eventRegistration->getPage() ), |
94 | $this->eventRegistration->getName() |
95 | ); |
96 | $ret = $this->msg( 'campaignevents-notification-registration-header-intro' ) |
97 | ->rawParams( $eventPageLink ) |
98 | ->escaped(); |
99 | |
100 | $chatURL = $this->eventRegistration->getChatURL(); |
101 | if ( $chatURL !== null ) { |
102 | $joinChatLink = $this->makeLink( |
103 | $chatURL, |
104 | $this->msg( 'campaignevents-notification-registration-header-chat-label' )->text() |
105 | ); |
106 | $ret .= Html::rawElement( |
107 | 'p', |
108 | [], |
109 | $this->msg( 'campaignevents-notification-registration-header-chat' ) |
110 | ->rawParams( $joinChatLink ) |
111 | ->escaped() |
112 | ); |
113 | } |
114 | |
115 | return new RawMessage( '$1', [ Message::rawParam( $ret ) ] ); |
116 | } |
117 | |
118 | /** |
119 | * @inheritDoc |
120 | */ |
121 | public function getBodyMessage() { |
122 | $body = Html::element( |
123 | 'h1', |
124 | [], |
125 | $this->msg( 'campaignevents-notification-registration-details-header' )->text() |
126 | ); |
127 | |
128 | $body .= $this->getDatesBodySection(); |
129 | $body .= $this->getTypeBodySection(); |
130 | $body .= $this->gerOrganizersBodySection(); |
131 | |
132 | $body = Html::rawElement( |
133 | 'div', |
134 | [ 'style' => 'font-weight:normal' ], |
135 | $body |
136 | ); |
137 | |
138 | return new RawMessage( '$1', [ Message::rawParam( $body ) ] ); |
139 | } |
140 | |
141 | /** |
142 | * @return string |
143 | */ |
144 | private function getDatesBodySection(): string { |
145 | $ret = Html::element( |
146 | 'h2', |
147 | [], |
148 | $this->msg( 'campaignevents-notification-registration-details-dates-header' )->text() |
149 | ); |
150 | |
151 | $formattedStart = $this->eventTimeFormatter->formatStart( |
152 | $this->eventRegistration, |
153 | $this->language, |
154 | $this->getUser() |
155 | ); |
156 | $formattedEnd = $this->eventTimeFormatter->formatEnd( |
157 | $this->eventRegistration, |
158 | $this->language, |
159 | $this->getUser() |
160 | ); |
161 | $datesMsg = $this->msg( 'campaignevents-notification-registration-details-dates' )->params( |
162 | $formattedStart->getTimeAndDate(), |
163 | $formattedStart->getDate(), |
164 | $formattedStart->getTime(), |
165 | $formattedEnd->getTimeAndDate(), |
166 | $formattedEnd->getDate(), |
167 | $formattedEnd->getTime() |
168 | )->text(); |
169 | $ret .= Html::element( 'p', [], $datesMsg ); |
170 | |
171 | $formattedTimezone = $this->eventTimeFormatter->formatTimezone( $this->eventRegistration, $this->getUser() ); |
172 | $timezoneMsg = $this->msg( 'campaignevents-notification-registration-details-dates-timezone' ) |
173 | ->params( $formattedTimezone ) |
174 | ->parse(); |
175 | $ret .= Html::rawElement( 'div', [], $timezoneMsg ); |
176 | |
177 | return $ret; |
178 | } |
179 | |
180 | /** |
181 | * @return string |
182 | */ |
183 | private function getTypeBodySection(): string { |
184 | $ret = Html::element( |
185 | 'h2', |
186 | [], |
187 | $this->msg( 'campaignevents-notification-registration-details-type-header' )->text() |
188 | ); |
189 | |
190 | $meetingType = $this->eventRegistration->getMeetingType(); |
191 | |
192 | if ( $meetingType & EventRegistration::MEETING_TYPE_ONLINE ) { |
193 | $ret .= Html::element( |
194 | 'h3', |
195 | [], |
196 | $this->msg( 'campaignevents-notification-registration-details-type-online-header' )->text() |
197 | ); |
198 | $meetingUrl = $this->eventRegistration->getMeetingURL(); |
199 | if ( $meetingUrl !== null ) { |
200 | $meetingLink = $this->makeLink( $meetingUrl, $meetingUrl ); |
201 | $ret .= Html::rawElement( 'p', [], $meetingLink ); |
202 | } |
203 | } |
204 | if ( $meetingType & EventRegistration::MEETING_TYPE_IN_PERSON ) { |
205 | $ret .= Html::element( |
206 | 'h3', |
207 | [], |
208 | $this->msg( 'campaignevents-notification-registration-details-type-in-person-header' )->text() |
209 | ); |
210 | $address = $this->eventRegistration->getMeetingAddress(); |
211 | $country = $this->eventRegistration->getMeetingCountry(); |
212 | if ( $address || $country ) { |
213 | $ret .= Html::element( |
214 | 'p', |
215 | [ 'style' => 'white-space: pre-wrap' ], |
216 | $address . "\n" . $country |
217 | ); |
218 | } |
219 | } |
220 | |
221 | return $ret; |
222 | } |
223 | |
224 | private function gerOrganizersBodySection(): string { |
225 | $ret = Html::element( |
226 | 'h2', |
227 | [], |
228 | $this->msg( 'campaignevents-notification-registration-details-organizers-header' )->text() |
229 | ); |
230 | |
231 | $partialOrganizers = $this->organizersStore->getEventOrganizers( |
232 | $this->eventRegistration->getID(), |
233 | self::ORGANIZERS_LIMIT |
234 | ); |
235 | $organizersCount = $this->organizersStore->getOrganizerCountForEvent( $this->eventRegistration->getID() ); |
236 | $organizerLinks = []; |
237 | foreach ( $partialOrganizers as $organizer ) { |
238 | try { |
239 | $organizerLinks[] = $this->userLinker->generateUserLink( $organizer->getUser() ); |
240 | } catch ( CentralUserNotFoundException | HiddenCentralUserException $_ ) { |
241 | // Can't easily include CSS styles in the message, so skip. |
242 | continue; |
243 | } |
244 | } |
245 | if ( $organizersCount > self::ORGANIZERS_LIMIT ) { |
246 | $moreOrganizersMsg = $this->msg( 'campaignevents-notification-registration-details-organizers-more' ) |
247 | ->numParams( $organizersCount - self::ORGANIZERS_LIMIT ) |
248 | ->text(); |
249 | $eventDetailsPage = SpecialPage::getTitleFor( |
250 | SpecialEventDetails::PAGE_NAME, |
251 | (string)$this->eventRegistration->getID() |
252 | ); |
253 | $organizerLinks[] = $this->makeLink( $eventDetailsPage->getFullURL(), $moreOrganizersMsg ); |
254 | } |
255 | $ret .= Html::rawElement( |
256 | 'p', |
257 | [], |
258 | $this->language->listToText( $organizerLinks ) |
259 | ); |
260 | |
261 | return $ret; |
262 | } |
263 | |
264 | /** |
265 | * @inheritDoc |
266 | */ |
267 | public function getPrimaryLink() { |
268 | return [ |
269 | 'url' => $this->pageUrlResolver->getFullUrl( $this->eventRegistration->getPage() ), |
270 | 'label' => $this->msg( 'campaignevents-notification-registration-event-page-link' )->text(), |
271 | ]; |
272 | } |
273 | |
274 | /** |
275 | * @inheritDoc |
276 | */ |
277 | public function getSecondaryLinks(): array { |
278 | $links = []; |
279 | |
280 | $chatURL = $this->eventRegistration->getChatURL(); |
281 | if ( $chatURL !== null ) { |
282 | $links[] = [ |
283 | 'url' => $chatURL, |
284 | 'label' => $this->msg( 'campaignevents-notification-registration-chat-link' )->text() |
285 | ]; |
286 | } |
287 | |
288 | return $links; |
289 | } |
290 | |
291 | /** |
292 | * @param string $url |
293 | * @param string $label Raw label, must not be escaped beforehand |
294 | * @return string |
295 | */ |
296 | private function makeLink( string $url, string $label ): string { |
297 | return Html::element( |
298 | 'a', |
299 | [ 'href' => $url ], |
300 | $label |
301 | ); |
302 | } |
303 | } |