Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 159
0.00% covered (danger)
0.00%
0 / 12
CRAP
0.00% covered (danger)
0.00%
0 / 1
RegistrationNotificationPresentationModel
0.00% covered (danger)
0.00%
0 / 159
0.00% covered (danger)
0.00%
0 / 12
600
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
2
 canRender
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 getIconType
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSubjectMessage
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 getHeaderMessage
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
6
 getBodyMessage
0.00% covered (danger)
0.00%
0 / 14
0.00% covered (danger)
0.00%
0 / 1
2
 getDatesBodySection
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
2
 getTypeBodySection
0.00% covered (danger)
0.00%
0 / 31
0.00% covered (danger)
0.00%
0 / 1
42
 gerOrganizersBodySection
0.00% covered (danger)
0.00%
0 / 30
0.00% covered (danger)
0.00%
0 / 1
20
 getPrimaryLink
0.00% covered (danger)
0.00%
0 / 4
0.00% covered (danger)
0.00%
0 / 1
2
 getSecondaryLinks
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 makeLink
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2declare( strict_types=1 );
3
4namespace MediaWiki\Extension\CampaignEvents\Notifications;
5
6use EchoEvent;
7use Language;
8use MediaWiki\Extension\CampaignEvents\CampaignEventsServices;
9use MediaWiki\Extension\CampaignEvents\Event\EventRegistration;
10use MediaWiki\Extension\CampaignEvents\Event\ExistingEventRegistration;
11use MediaWiki\Extension\CampaignEvents\MWEntity\CentralUserNotFoundException;
12use MediaWiki\Extension\CampaignEvents\MWEntity\HiddenCentralUserException;
13use MediaWiki\Extension\CampaignEvents\MWEntity\PageURLResolver;
14use MediaWiki\Extension\CampaignEvents\MWEntity\UserLinker;
15use MediaWiki\Extension\CampaignEvents\Organizers\OrganizersStore;
16use MediaWiki\Extension\CampaignEvents\Special\SpecialEventDetails;
17use MediaWiki\Extension\CampaignEvents\Time\EventTimeFormatter;
18use MediaWiki\Extension\Notifications\Formatters\EchoEventPresentationModel;
19use MediaWiki\Html\Html;
20use MediaWiki\Language\RawMessage;
21use MediaWiki\SpecialPage\SpecialPage;
22use MediaWiki\User\User;
23use Message;
24
25class 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}