Code source wiki de Invitation
Modifié par superadmin le 2026/01/29 15:29
Afficher les derniers auteurs
| author | version | line-number | content |
|---|---|---|---|
| 1 | {{include reference="Invitation.InvitationCommon" /}} | ||
| 2 | |||
| 3 | {{include reference="Invitation.InvitationMembersCommon" /}} | ||
| 4 | |||
| 5 | {{velocity}} | ||
| 6 | #* | ||
| 7 | * Invitation Application | ||
| 8 | * This script is only for sending messages and users who are not allowed to send mail need not have access to | ||
| 9 | * view this page. | ||
| 10 | * | ||
| 11 | * Macros in this script don't rely on any variables except those which are passed to them and the following: | ||
| 12 | * | ||
| 13 | * $doc the com.xpn.xwiki.api.Document object representing the document containing this code. | ||
| 14 | * $msg the internationalization message provider containing a get(String) and a get(String, List) function | ||
| 15 | * $xcontext the com.xpn.xwiki.Context object for this request | ||
| 16 | * $xwiki an object of the com.xpn.xwiki.api.XWiki class. | ||
| 17 | * | ||
| 18 | * Macros also depend on other macros but only other macros which are contained in this script. | ||
| 19 | * | ||
| 20 | * This script relies on the following documents: | ||
| 21 | * | ||
| 22 | * InvitationCommon | ||
| 23 | * | ||
| 24 | * InvitationMembersCommon | ||
| 25 | * | ||
| 26 | * | ||
| 27 | * This script is affected by the following documents: | ||
| 28 | * | ||
| 29 | * InvitationMessages stores all of the mail message objects. If this does not exist it will be created. | ||
| 30 | * May be changed in the configuration. | ||
| 31 | * | ||
| 32 | * InvitationMailClass the class for mail message objects. May be changed in the configuration. | ||
| 33 | * | ||
| 34 | * InvitationConfig configuration for this code. Contains an XObject of the class defined in this document. | ||
| 35 | * If it does not exist it will be created with default values. | ||
| 36 | * | ||
| 37 | *### | ||
| 38 | #if($xcontext.getUser() == 'XWiki.XWikiGuest') | ||
| 39 | ## Only members should ever have access to this document, enforce this through XWiki permissions system, | ||
| 40 | ## this is a last effort in the event of incorrect settings. | ||
| 41 | #stop | ||
| 42 | #end | ||
| 43 | ## | ||
| 44 | ## is the user a mail admin TODO: change this. | ||
| 45 | #set($isAdmin = $hasEdit) | ||
| 46 | ## | ||
| 47 | ## Load config and mail. | ||
| 48 | #set($config = {}) | ||
| 49 | #loadInvitationConfig($config) | ||
| 50 | #set($mail = {}) | ||
| 51 | #set($emailContainer = $xwiki.getDocumentAsAuthor($config.get('emailContainer'))) | ||
| 52 | #loadInvitationMail($config, $emailContainer, $mail) | ||
| 53 | ## | ||
| 54 | ## Load CSS | ||
| 55 | $xwiki.get('ssx').use($config.get('commonPage')) | ||
| 56 | ## | ||
| 57 | ## Don't load comments, history, etc. | ||
| 58 | #set ($displayDocExtra = false) | ||
| 59 | ## | ||
| 60 | #displayInvitationHeader($request.getParameterMap(), $config) | ||
| 61 | ## | ||
| 62 | ##--------------------------------------------------------------------- | ||
| 63 | ## Decide what we should do. | ||
| 64 | ##--------------------------------------------------------------------- | ||
| 65 | ## | ||
| 66 | #if($xcontext.getAction() != 'view') | ||
| 67 | ## The administration application includes this page so we will not do anything. | ||
| 68 | #elseif(!$isAdmin && "#isUserReportedSpammer($mail.values())" != 'false') | ||
| 69 | ## The current user has been reported as a spammer, they are not allowed to send more mail until | ||
| 70 | ## the situation has been investigated. | ||
| 71 | |||
| 72 | ## A message which you sent was reported as spam and your privilege to send mail has been suspended... | ||
| 73 | (%id="invitation-permission-error"%)((({{error}}$services.localization.render('xe.invitation.userIsReportedSpammer'){{/error}}))) | ||
| 74 | ## | ||
| 75 | #elseif(!$isAdmin | ||
| 76 | && $config.get('allowUsersOfOtherWikis') != '1' | ||
| 77 | && $doc.getWiki() != $xwiki.getDocument($xcontext.getUser()).getWiki()) | ||
| 78 | ## Users of other subwikis are not allowed to send mail. | ||
| 79 | (%id="invitation-permission-error"%)((({{error}}$services.localization.render('xe.invitation.onlyMembersCanSendMail') | ||
| 80 | $services.localization.render('xe.invitation.youAreAMemberOfOtherWiki', [$xwiki.getDocument($xcontext.getUser()).getWiki()]){{/error}}))) | ||
| 81 | #else | ||
| 82 | ## The user is authorized to send mail <------------------------------------------------------- | ||
| 83 | ## Get the list of email addresses to send to. | ||
| 84 | #set($userMaySendToMultiple = ($isAdmin || $config.get('usersMaySendToMultiple') == '1')) | ||
| 85 | #set($recipientString = $escapetool.xml("$!request.get('recipients')")) | ||
| 86 | #set($recipients = []) | ||
| 87 | #getRecipients($recipientString, $userMaySendToMultiple, $recipients) | ||
| 88 | ## | ||
| 89 | ## get subject line and message body if allowed... | ||
| 90 | #set($userMayPersonalizeMessage = ($isAdmin || $config.get('usersMayPersonalizeMessage') == '1')) | ||
| 91 | #if($userMayPersonalizeMessage) | ||
| 92 | #set($subjectLine = $request.get('subjectLine')) | ||
| 93 | #set($messageBody = $request.get('messageBody')) | ||
| 94 | #else | ||
| 95 | #set($subjectLine = '') | ||
| 96 | #set($messageBody = '') | ||
| 97 | #end | ||
| 98 | ## | ||
| 99 | #if("$!request.get('sendMail')" != '' | ||
| 100 | && $request.getMethod().toLowerCase() == 'post' | ||
| 101 | && ${services.csrf.isTokenValid("$!{request.getParameter('form_token')}")}) | ||
| 102 | #generateAndSendMail($config, | ||
| 103 | $recipients, | ||
| 104 | $subjectLine, | ||
| 105 | $messageBody) | ||
| 106 | ## Reload mail so footer information is correct. | ||
| 107 | #set($mail = {}) | ||
| 108 | #loadInvitationMail($config, $emailContainer, $mail) | ||
| 109 | #else | ||
| 110 | ## The user wants to write and preview a message. | ||
| 111 | #displayForm($recipientString, | ||
| 112 | $subjectLine, | ||
| 113 | $messageBody, | ||
| 114 | $userMaySendToMultiple, | ||
| 115 | $userMayPersonalizeMessage) | ||
| 116 | #set($messages = []) | ||
| 117 | ## No recipients ('',) because we are just creating it to preview. | ||
| 118 | #set($emailContainer = $xwiki.getDocumentAsAuthor($config.get('emailContainer'))) | ||
| 119 | #generateMailFromTemplate($config.get('subjectLineTemplate'), | ||
| 120 | $config.get('messageBodyTemplate'), | ||
| 121 | $config.get('emailClass'), | ||
| 122 | [], | ||
| 123 | $config.get('emailRegex'), | ||
| 124 | $subjectLine, | ||
| 125 | $messageBody, | ||
| 126 | $messages, | ||
| 127 | $emailContainer) | ||
| 128 | #set($invalidAddresses = []) | ||
| 129 | #validateAddressFormat($recipients, $config.get('emailRegex'), $invalidAddresses) | ||
| 130 | #displayMessage($messages.get(0), $recipients, $invalidAddresses) | ||
| 131 | #end | ||
| 132 | #invitationFooter($mail, $request.getParameterMap(), $isAdmin, $config) | ||
| 133 | #end##if user has permission to send | ||
| 134 | ## | ||
| 135 | ##--------------------------------------------------------------------- | ||
| 136 | ## The macros (Nothing below this point is run directly) | ||
| 137 | ##--------------------------------------------------------------------- | ||
| 138 | ## | ||
| 139 | #* | ||
| 140 | * Generate and send an email message. | ||
| 141 | * | ||
| 142 | * $messages (List<XObject>) a list of invitation email messages. | ||
| 143 | * | ||
| 144 | * $config (XObject) configuration for the inviter. | ||
| 145 | * | ||
| 146 | * $emailContainer (Document) the document contaning the mail message. | ||
| 147 | *### | ||
| 148 | #macro(generateAndSendMail, $config, $recipients, $messageSubject, $messageContent) | ||
| 149 | #set($messages = []) | ||
| 150 | #set($emailContainer = $xwiki.getDocumentAsAuthor($config.get('emailContainer'))) | ||
| 151 | #generateMailFromTemplate($config.get('subjectLineTemplate'), | ||
| 152 | $config.get('messageBodyTemplate'), | ||
| 153 | $config.get('emailClass'), | ||
| 154 | $recipients, | ||
| 155 | $config.get('emailRegex'), | ||
| 156 | $messageSubject, | ||
| 157 | $messageContent, | ||
| 158 | $messages, | ||
| 159 | $emailContainer) | ||
| 160 | ## | ||
| 161 | #if($messages.size() > 0) | ||
| 162 | #sendMail($messages, $config, $emailContainer) | ||
| 163 | #set($errors = []) | ||
| 164 | #foreach($message in $messages) | ||
| 165 | #set($status = $message.getProperty('status').getValue()) | ||
| 166 | #if($status != 'pending') | ||
| 167 | #set($discard = $errors.add($message)) | ||
| 168 | #end | ||
| 169 | #end | ||
| 170 | (%class="invitation"%)((( | ||
| 171 | |||
| 172 | (%id="invitation-action-message"%)(((## | ||
| 173 | #if($errors.size() > 0) | ||
| 174 | ## An error has occured while sending the message. | ||
| 175 | {{error}}$services.localization.render('xe.invitation.errorWhileSending'){{/error}}## | ||
| 176 | #else | ||
| 177 | ## Your message has been sent. | ||
| 178 | {{info}}$services.localization.render('xe.invitation.successSending'){{/info}}## | ||
| 179 | #end | ||
| 180 | ))) | ||
| 181 | |||
| 182 | #displayMessageTable($messages, ['sentDate', 'recipient', 'status']) | ||
| 183 | ))) | ||
| 184 | #displayMessage($messages.get(0), $recipients) | ||
| 185 | #else | ||
| 186 | |||
| 187 | |||
| 188 | (%id="invitation-action-message"%)((({{error}}$services.localization.render('xe.invitation.noValidMessagesToSend'){{/error}}))) | ||
| 189 | |||
| 190 | #end | ||
| 191 | #end | ||
| 192 | #* | ||
| 193 | * Send an email message. | ||
| 194 | * | ||
| 195 | * $messages (List<XObject>) a list of invitation email messages. | ||
| 196 | * | ||
| 197 | * $config (XObject) configuration for the inviter. | ||
| 198 | * | ||
| 199 | * $emailContainer (Document) the document contaning the mail messages. | ||
| 200 | *### | ||
| 201 | #macro(sendMail, $messages, $config, $emailContainer) | ||
| 202 | ## | ||
| 203 | ## Get mail sender plugin. | ||
| 204 | #set($sender = $xwiki.get('mailsender')) | ||
| 205 | ## | ||
| 206 | ## If parameters are set in the local config, use them, otherwise use global defaults. | ||
| 207 | #set($senderConfig = $sender.createMailConfiguration($xwiki)) | ||
| 208 | #if("$!config.get('smtp_server')" != '') | ||
| 209 | $senderConfig.setHost($config.get('smtp_server'))## | ||
| 210 | #end | ||
| 211 | #if("$!config.get('smtp_port')" != '') | ||
| 212 | $senderConfig.setPort($numbertool.toNumber($config.get('smtp_port')).intValue())## | ||
| 213 | #end | ||
| 214 | #if("$!config.get('smtp_server_username')" != '') | ||
| 215 | $senderConfig.setSmtpUsername($config.get('smtp_server_username'))## | ||
| 216 | #end | ||
| 217 | #if("$config.containsKey('smtp_server_password')" != '') | ||
| 218 | $senderConfig.setSmtpPassword($config.get('smtp_server_password'))## | ||
| 219 | #end | ||
| 220 | #if("$config.containsKey('javamail_extra_props')" != '') | ||
| 221 | $senderConfig.setExtraProperties($config.get('javamail_extra_props'))## | ||
| 222 | #end | ||
| 223 | ## | ||
| 224 | #foreach($message in $messages) | ||
| 225 | #set($mailObj = $sender.createMail()) | ||
| 226 | ## | ||
| 227 | #if("$config.get('from_address')" != '') | ||
| 228 | $mailObj.setFrom($config.get('from_address'))## | ||
| 229 | #end | ||
| 230 | ## | ||
| 231 | ## Set recipients | ||
| 232 | #set($recipient = $message.getProperty('recipient').getValue())## | ||
| 233 | $mailObj.setTo($recipient)## | ||
| 234 | ## | ||
| 235 | ## Set the subject line and message body. | ||
| 236 | $mailObj.setSubject($message.getProperty('subjectLine').getValue())## | ||
| 237 | ## | ||
| 238 | ## If text part is not set then we get an NPE when trying to craft a multipart message. | ||
| 239 | $mailObj.setTextPart('')## | ||
| 240 | ## Put all in email div so that we can apply CSS only to the email and not to the preview. | ||
| 241 | $mailObj.setHtmlPart("<div style='font-size:87.5%;'>$message.getProperty('messageBody').getValue()</div>")## | ||
| 242 | ## | ||
| 243 | ## Send the message | ||
| 244 | #if("$sender.sendMail($mailObj, $senderConfig)" != 0) | ||
| 245 | #setMessageStatus($message, 'sendingFailed')## | ||
| 246 | #else | ||
| 247 | #setMessageStatus($message, 'pending', $services.localization.render('xe.invitation.messageSentLogEntry'))## | ||
| 248 | #end | ||
| 249 | #end | ||
| 250 | ## Comment = "Added Email Message(s)." | ||
| 251 | $emailContainer.saveAsAuthor($services.localization.render('xe.invitation.sendMail.addMessageSaveComment')) | ||
| 252 | #end | ||
| 253 | ## | ||
| 254 | #* | ||
| 255 | * Generate invitation XObjects from a template, user input, and a set of recipients. | ||
| 256 | * | ||
| 257 | * $subjectLineTemplate (String) this will be evaluated as velocity and placed in the email subject line. | ||
| 258 | * You may refer to $messageID and $subjectLine in the code. | ||
| 259 | * | ||
| 260 | * $messageBodyTemplate (String) this will be evaluated as velocity and placed in the email message body. | ||
| 261 | * You may refer to $messageID, $messageBody, You may also use xwiki2.0 syntax | ||
| 262 | * in the template. | ||
| 263 | * | ||
| 264 | * $emailClass (String) the document name of the XClass representing email messages. | ||
| 265 | * | ||
| 266 | * $recipients (List<String>) email addresses to send this message to. | ||
| 267 | * | ||
| 268 | * $emailRegex (String) the regular expression to validate the email addresses against. Undefined behavior will result | ||
| 269 | * from an invalid expression. | ||
| 270 | * | ||
| 271 | * $userSuppliedSubject (String) the message subject. This can be modified or ignored by the template. | ||
| 272 | * | ||
| 273 | * $userSuppliedContent (String) the message content. This can be modified or ignored by the template. | ||
| 274 | * | ||
| 275 | * $messages (List<XObject>) this list will be populated with mail objects for each recipient. | ||
| 276 | * | ||
| 277 | * $emailContainer (Document) the document where the mail object will be stored for later review. | ||
| 278 | *### | ||
| 279 | #macro(generateMailFromTemplate, $subjectLineTemplate, $messageBodyTemplate, $emailClass, $recipients, $emailRegex, | ||
| 280 | $userSuppliedSubject, $userSuppliedContent, $messages, $emailContainer) | ||
| 281 | #if($recipients && $recipients.size() > 0) | ||
| 282 | #set($sendTo = []) | ||
| 283 | #set($discard = $sendTo.addAll($recipients)) | ||
| 284 | #set($invalid = []) | ||
| 285 | #validateAddressFormat($recipients, $emailRegex, $invalid) | ||
| 286 | #set($discard = $sendTo.removeAll($invalid)) | ||
| 287 | #set($messageGroupID = $mathtool.getRandom()) | ||
| 288 | #else | ||
| 289 | ## If we're just doing a test run, no recipients but we still want to generate a message. | ||
| 290 | #set($sendTo = ['']) | ||
| 291 | #end | ||
| 292 | ## | ||
| 293 | #foreach($recipient in $sendTo) | ||
| 294 | #set($message = $emailContainer.newObject($emailClass)) | ||
| 295 | $message.set('sendingUser', $xcontext.getUser())## | ||
| 296 | $message.set('sentDate', '')## | ||
| 297 | $message.set('messageGroupID', $messageGroupID)## | ||
| 298 | $message.set('recipient', $recipient)## | ||
| 299 | ## Set the message id to a random number string, set it to $messageID variable so it can be used by the template. | ||
| 300 | #set($messageID = "$mathtool.getRandom().toString().replaceAll('\.','')## | ||
| 301 | $mathtool.getRandom().toString().replaceAll('\.','')## | ||
| 302 | $mathtool.getRandom().toString().replaceAll('\.','')") | ||
| 303 | $message.set('messageID', $messageID)## | ||
| 304 | ## | ||
| 305 | ## Need to make $subjectLine and $messageBody available to $doc.getRenderedContent. | ||
| 306 | #set($subjectLine = "$!userSuppliedSubject") | ||
| 307 | #set($messageBody = "$!userSuppliedContent") | ||
| 308 | ## | ||
| 309 | ## If the subject line provided by the user is empty then there will be trailing whitespace. | ||
| 310 | ## xe.invitation.emailContent.subjectLine={0} has invited you to join {1} {2} | ||
| 311 | #set($subjectLineWithWhitespace = "$doc.getRenderedContent($subjectLineTemplate, 'xwiki/2.0', 'plain/1.0')") | ||
| 312 | ## | ||
| 313 | ## Generate the message from the template - html in the subject line is ignored by the mail client. | ||
| 314 | $message.set('subjectLine', $subjectLineWithWhitespace.trim())## | ||
| 315 | $message.set('messageBody', "$doc.getRenderedContent($messageBodyTemplate, 'xwiki/2.0')")## | ||
| 316 | #set($discard = $messages.add($message)) | ||
| 317 | #end | ||
| 318 | #end | ||
| 319 | ## | ||
| 320 | #* | ||
| 321 | * Check the format of an email address against a regular expression. | ||
| 322 | * | ||
| 323 | * $allAddresses (List<String>) The list of addresses to validate. | ||
| 324 | * | ||
| 325 | * $emailRegex (String) The regular expression to validate the email addresses agains. Undefined behavior will result | ||
| 326 | * from an invalid expression. | ||
| 327 | * | ||
| 328 | * $invalidAddresses (List<String>) this List will be populated with addresses from $allAddresses which are invalid. | ||
| 329 | *### | ||
| 330 | #macro(validateAddressFormat, $allAddresses, $emailRegex, $invalidAddresses) | ||
| 331 | ## Perl/javascript regexes look like /^.*/ | ||
| 332 | ## java does not like the / at beginning and end. | ||
| 333 | #if($emailRegex.length() > 1) | ||
| 334 | #set($emailRegexInternal = $emailRegex.substring(1, $mathtool.add($emailRegex.length(), -1))) | ||
| 335 | #else | ||
| 336 | ## I don't expect this but want to maintain compatibility. | ||
| 337 | #set($emailRegexInternal = $emailRegex) | ||
| 338 | #end | ||
| 339 | #foreach($address in $allAddresses) | ||
| 340 | #if("$!address" == '') | ||
| 341 | ## Empty address, do nothing. | ||
| 342 | #elseif($regextool.find($address, $emailRegexInternal).size() == 0) | ||
| 343 | #set($discard = $invalidAddresses.add($address)) | ||
| 344 | #end | ||
| 345 | #end | ||
| 346 | #end | ||
| 347 | ## | ||
| 348 | #* | ||
| 349 | * Display a form for typing up an invitation email. | ||
| 350 | * | ||
| 351 | * $recipientString (String) what should be filled in to the field for recipients. | ||
| 352 | * | ||
| 353 | * $subjectLine (String) what should be put in the subject line by default. | ||
| 354 | * | ||
| 355 | * $messageBody (String) what should be put in the content of the message by default. | ||
| 356 | * | ||
| 357 | * $userMaySendToMultiple (Boolean) true if the current user has permission send to multiple addresses at once. | ||
| 358 | * | ||
| 359 | * $userMayPersonalizeMessage (Boolean) true if the user may add their own subject line and message content. | ||
| 360 | *### | ||
| 361 | #macro(displayForm, $recipientString, $subjectLine, $messageBody, $userMaySendToMultiple, $userMayPersonalizeMessage) | ||
| 362 | |||
| 363 | {{html clean="false" wiki="false"}} | ||
| 364 | <form id="invitation-sender-form" action="$doc.getURL('view')" method="post" class="invitation"> | ||
| 365 | <div class="hidden"><input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /></div> | ||
| 366 | <dl> | ||
| 367 | ## Who you are inviting: | ||
| 368 | <dt><label for="recipients">$services.localization.render('xe.invitation.toLabel')</label></dt> | ||
| 369 | ## If the user has edit access on this document, then we should allow them to send to multiple email addresses. | ||
| 370 | #if($userMaySendToMultiple) | ||
| 371 | <dd> | ||
| 372 | <textarea cols="75" name="recipients" rows="3" id="recipients">## | ||
| 373 | $!recipientString## | ||
| 374 | </textarea> | ||
| 375 | </dd> | ||
| 376 | #else | ||
| 377 | <dd><input type="text" size="54" name="recipients" id="recipients" value="$!recipientString" /></dd> | ||
| 378 | #end | ||
| 379 | #if($userMayPersonalizeMessage) | ||
| 380 | ## Subject line: | ||
| 381 | <dt><label for="subjectLine">$services.localization.render('xe.invitation.subjectLabel')</label></dt> | ||
| 382 | <dd> | ||
| 383 | <input type="text" size="54" name="subjectLine" id="subjectLine" value="$!escapetool.xml($!subjectLine)" /> | ||
| 384 | </dd> | ||
| 385 | ## Invitation message: | ||
| 386 | <dt><label for="messageBody">$services.localization.render('xe.invitation.contentLabel')</label></dt> | ||
| 387 | <dd> | ||
| 388 | <textarea cols="75" name="messageBody" rows="10" id="messageBody">## | ||
| 389 | $!escapetool.xml($!messageBody)## | ||
| 390 | </textarea> | ||
| 391 | </dd> | ||
| 392 | #end | ||
| 393 | </dl> | ||
| 394 | <div class="bottombuttons"> | ||
| 395 | <div class="buttons"> | ||
| 396 | <span class="buttonwrapper"> | ||
| 397 | ## Preview | ||
| 398 | <input type="submit" class="button" name="preview" value="$services.localization.render('xe.invitation.displayForm.preview')" /> | ||
| 399 | </span> | ||
| 400 | <span class="buttonwrapper"> | ||
| 401 | ## Send Mail | ||
| 402 | <input type="submit" class="button" name="sendMail" value="$services.localization.render('xe.invitation.displayForm.sendMail')" /> | ||
| 403 | </span> | ||
| 404 | </div> | ||
| 405 | </div> | ||
| 406 | </form> | ||
| 407 | {{/html}} | ||
| 408 | |||
| 409 | #end | ||
| 410 | ## | ||
| 411 | #* | ||
| 412 | * Has mail sent by the current user been reported as spam? | ||
| 413 | * will return 'false' if not otherwise will return 'true' | ||
| 414 | * if a message was reported as spam but an admin has marked the situation | ||
| 415 | * as handled then this macro will return 'false' | ||
| 416 | * | ||
| 417 | * $messages (Collection<XObject>) objects representing all email messages. | ||
| 418 | *### | ||
| 419 | #macro(isUserReportedSpammer, $messages) | ||
| 420 | #set($out = 'false') | ||
| 421 | #foreach($message in $messages) | ||
| 422 | #if($message.getProperty('sendingUser').getValue() == $xcontext.getUser() | ||
| 423 | && $message.getProperty('status').getValue() == 'reported') | ||
| 424 | ## | ||
| 425 | #set($out = 'true') | ||
| 426 | #end | ||
| 427 | #end | ||
| 428 | $out## | ||
| 429 | #end | ||
| 430 | ## | ||
| 431 | #* | ||
| 432 | * Get the list of recipients from the user input string. | ||
| 433 | * Splits on space but is tolerent of commas. | ||
| 434 | * Each email in the list may only appear in the output once (no duplicates.) | ||
| 435 | * | ||
| 436 | * $recipientString (String) the String input by the user eg: "alice@example.com bob@example.com" | ||
| 437 | * | ||
| 438 | * $userMaySendToMultiple (Boolean) is the user allowed to send to multiple addresses at once? | ||
| 439 | * | ||
| 440 | * $recipientsOut (List<String>) is populated with one or more email addresses. | ||
| 441 | *### | ||
| 442 | #macro(getRecipients, $recipientString, $userMaySendToMultiple, $recipientsOut) | ||
| 443 | #if($userMaySendToMultiple) | ||
| 444 | #set($recipientsArray = $recipientString.replaceAll(', ', ' ').split(' ')) | ||
| 445 | #set($recipientMap = {}) | ||
| 446 | #foreach($recip in $recipientsArray) | ||
| 447 | #set($discard = $recipientMap.put($recip, 0)) | ||
| 448 | #end | ||
| 449 | #set($discard = $recipientsOut.addAll($recipientMap.keySet())) | ||
| 450 | #else | ||
| 451 | ## If the user can't edit this page, we won't let them sent to multiple addresses. | ||
| 452 | #set($discard = $recipientsOut.add($recipientString)) | ||
| 453 | #end | ||
| 454 | #end | ||
| 455 | {{/velocity}} |