Code source wiki de Invitation

Modifié par superadmin le 2026/01/29 15:29

Afficher les derniers auteurs
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}}