General Actions:
Log-in
Register
Wiki:
games
▼
:
Document Index
»
Space:
Invitation
▼
:
Document Index
»
Page:
InvitationCommon
Search
en
Page Actions:
Export
▼
:
Export as PDF
Export as RTF
Export as HTML
More actions
▼
:
Print preview
View Source
Invitation.WebHome
»
InvitationCommon
Wiki source code of
InvitationCommon
Last modified by
Administrator
on 2011/11/06 20:09
Content
·
Comments
(0)
·
Annotations
(0)
·
Attachments
(0)
·
History
·
Information
Hide line numbers
1: {{velocity}} 2: #* 3: * Invitation Application 4: * This document contains common macros used by all documents in the Invitation Application. 5: * 6: * Macros in this script don't rely on any variables except those which are passed to them and the following: 7: * 8: * $doc the com.xpn.xwiki.api.Document object representing the document containing this code. 9: * $msg the internationalization message provider containing a get(String) and a get(String, List) function 10: * $xcontext the com.xpn.xwiki.Context object for this request 11: * $xwiki an object of the com.xpn.xwiki.api.XWiki class. 12: * $escapetool an object of class org.apache.velocity.tools.generic.EscapeTool 13: * $util used to get a newline character ($util.getNewLine()) 14: * 15: * No macros in this script depend on any other macros. 16: *### 17: ## 18: #if($request.getParameter('test') == '1') 19: {{info}}testLoadInvitationConfig{{/info}} 20: #testLoadInvitationConfig() 21: #elseif($doc.getName() == 'InvitationCommon') 22: {{info}}$msg.get("xe.invitation.internalDocument", ["${doc.getSpace()}.WebHome"]){{/info}} 23: #end 24: ## 25: #* 26: * Display a message for the sender (preview) or for the admin (review sent messages) 27: * 28: * $mail (XObject representing email message) the message to view 29: * 30: * $recipients (List<String>) (Optional) the list of email addresses to override the list provided by $mail 31: * used for preview because createMailFromTemplate will exclude addresses 32: * which are invalid and we want to show the invalid addresses to the 33: * user to tell them that they need to correct them. 34: * 35: * $invalidAddresses (List<String>) (Optional) List of invalid email addresses in recipients. Needed if you want to 36: * show the user that they made a mistake on some addresses. 37: * For each email in $invalidEmails, if it is also in $recipients, then it 38: * will be marked but left in the same order, emails in $invlaidEmails but 39: * not found in $recipients will end up at the end of the list. 40: *### 41: #macro(displayMessage, $mail, $recipients, $invalidAddresses) 42: 43: {{html wiki=false clean=false}} 44: <div id="invitation-displaymessage" class="invitation"> 45: <strong>$msg.get('xe.invitation.previewLabel')</strong> 46: <div class="invitation invitation-preview"> 47: #set($recips = []) 48: #set($invalid = []) 49: ## get the lists of valid and invalid email addresses. 50: #if("$!invalidAddresses" == '') 51: #set($invalid = []) 52: #if("$!recipients" == '') 53: #set($recips = [$mail.getProperty('recipient').getValue().trim()]) 54: #else 55: #set($discard = $recips.addAll($recipients)) 56: #end 57: #else 58: ## Set to local variables to prevent altering input values. 59: #set($discard = $recips.addAll($recipients)) 60: #set($discard = $invalid.addAll($invalidAddresses)) 61: #end 62: ## Print the email addresses to be sent to. 63: ## To: 64: <strong>$msg.get('xe.invitation.toLabel')</strong> 65: <div id="preview-to-field" class="invitation-preview field"> 66: #foreach($recip in $recips) 67: #if($invalid.contains($recip)) 68: <span class="invalid-address">$!escapetool.xml($!recip)</span> ## 69: #set($discard = $invalid.remove($recip)) 70: #else 71: <span class="valid-address">$!escapetool.xml($!recip)</span> ## 72: #end 73: #end 74: #foreach($recip in $invalid) 75: <span class="invalid-address">$!escapetool.xml($!recip)</span> ## 76: #end 77: ## used to make the field the correct size if it's empty. 78: </div> 79: ## Tell the user that some of the email addresses are invalid. 80: #if($invalidAddresses && $invalidAddresses.size() > 0) 81: <p class="invalid-address-message"> 82: <span class="errormessage"> 83: #if($recips.size() == 1) 84: ## The email address given is invalid and will not be sent to. 85: $msg.get('xe.invitation.displayMessage.theAddressIsInvalid') 86: #else 87: #if($invalid.size() > 1) 88: $msg.get('xe.invitation.displayMessage.someAddressesAreInvalid', [$invalidAddresses.size()]) 89: #else 90: $msg.get('xe.invitation.displayMessage.anAddressesIsInvalid') 91: #end 92: #end 93: </span> 94: </p> 95: #end 96: ## Subject: 97: <strong>$msg.get('xe.invitation.subjectLabel')</strong> 98: <div id="preview-subjectline-field" class="invitation-preview field"> 99: $escapetool.xml($mail.getProperty('subjectLine').getValue()) 100: </div> 101: ## Message: 102: <strong>$msg.get('xe.invitation.contentLabel')</strong> 103: <div id="preview-messagebody-field" class="invitation-preview field"> 104: $mail.getProperty('messageBody').getValue() 105: </div> 106: </div> 107: </div> 108: {{/html}} 109: 110: #end 111: ## 112: #* 113: * Load the configuration. 114: * Only works if the script calling this macro has permission to view InvitationConfig 115: * (or create it if it doesn't exist) 116: * 117: * $config (Map<String, String>) will be populated with invitation configuration. 118: * 119: * $configDocName (String) (Optional) will load configuration from this document, if not specified will use 120: * 'InvitationConfig' in the same space as $doc. 121: * 122: * $configClassName (String) (Optional) will load configuration from object of this class, if not specified will use 123: * 'Invitation' in the same space as $doc. 124: *### 125: #macro(loadInvitationConfig, $config, $configDocName, $configClassName) 126: #define($discard) 127: #if("$!configDocName" == '') 128: #set($configDocNameInternal = "${doc.getSpace()}.InvitationConfig") 129: #else 130: #set($configDocNameInternal = $configDocName) 131: #end 132: #if("$!configClassName" == '') 133: #set($configClassNameInternal = "${doc.getSpace()}.WebHome") 134: #else 135: #set($configClassNameInternal = $configClassName) 136: #end 137: ## 138: ## Load some parameters from the configuration. 139: #set($configDoc = $xwiki.getDocumentAsAuthor($configDocNameInternal)) 140: ## 141: ## If no configuration document exists, create one and save it. 142: #if($configDoc.isNew()) 143: ## 144: ## load the default configuration from this document. 145: #set($thisDocument = $xwiki.getDocumentAsAuthor("${doc.getSpace()}.InvitationCommon")) 146: #set($defaultConfigObj = $thisDocument.getObject($configClassNameInternal)) 147: #foreach($element in $defaultConfigObj.getProperties()) 148: $config.put($element.getName(), $defaultConfigObj.getProperty($element.getName()).getValue()) 149: #end 150: ## 151: #set($configDocContent = '{{velo' + 'city}}{{info}}$msg.get("xe.invitation.internalDocument", ["' 152: + "$!config.get('mainPage')" + '"]){{/info}}{{/velo' + 'city}}') 153: $configDoc.setContent($configDocContent) 154: $configDoc.setParent($configClassNameInternal) 155: #set($configObj = $configDoc.newObject($configClassNameInternal)) 156: #foreach($key in $config.keySet()) 157: $configObj.set($key, $config.get($key)) 158: #end 159: ## Now create the configurable objects. 160: #set($cfgable = $configDoc.newObject('XWiki.ConfigurableClass')) 161: $cfgable.set('displayInSection', 'Invitation') 162: $cfgable.set('configurationClass', $configClassNameInternal) 163: $cfgable.set('configureGlobally', 1) 164: #set($propsToShow = 'subjectLineTemplate|messageBodyTemplate|emailRegex|from_address|allowUsersOfOtherWikis' 165: + '|usersMayPersonalizeMessage|usersMaySendToMultiple|emailClass|emailContainer') 166: $cfgable.set('propertiesToShow', $propsToShow) 167: #set($cfgable = $configDoc.newObject('XWiki.ConfigurableClass')) 168: $cfgable.set('displayInSection', 'Invitation') 169: $cfgable.set('heading', '$msg.get("xe.invitation.configuration.smtpHeading")') 170: $cfgable.set('configurationClass', $configClassNameInternal) 171: $cfgable.set('configureGlobally', 1) 172: $cfgable.set('propertiesToShow', 173: 'smtp_server_password|smtp_server_username|smtp_port|smtp_server|javamail_extra_props') 174: $configDoc.saveAsAuthor() 175: #else 176: ## load the configuration object... 177: #set($configObj = $configDoc.getObject($configClassNameInternal)) 178: #foreach($element in $configObj.getProperties()) 179: $config.put($element.getName(), $configObj.getProperty($element.getName()).getValue()) 180: #end 181: #end 182: #end## define $discard 183: ## Now invoke the defined code... 184: #set($discard = $discard.toString()) 185: #end 186: ## 187: #* 188: * Basic unit testing of the macro above. 189: *### 190: #macro(testLoadInvitationConfig) 191: #set($configDoc = $xwiki.getDocumentAsAuthor("${doc.getSpace()}.InvitationConfig")) 192: #if(!$configDoc.isNew()) 193: $configDoc.deleteAsAuthor() 194: #end 195: #set($configClass = $xwiki.getDocumentAsAuthor("${doc.getSpace()}.WebHome")) 196: #if($configClass.isNew()) 197: {{error}}Class document [[${doc.getSpace()}.WebHome]] not found. can't run test.{{/error}} 198: #else 199: #set($config = {}) 200: #loadInvitationConfig($config, 'HopefullyNonexistantSpace') 201: #if($config.size() < 9) 202: {{error}}Config map too small{{/error}} 203: #end 204: #if($config.get('from_address') != 'no-reply@localhost.localdomain') 205: {{error}}form_address incorrect, expecting "no-reply@localhost.localdomain" got "$config.get('from_address')"{{/error}} 206: #end 207: #set($configDoc = $xwiki.getDocumentAsAuthor("${doc.getSpace()}.InvitationConfig")) 208: #if($configDoc.isNew()) 209: {{error}}Config document not created{{/error}} 210: #else 211: #set($configObj = $configDoc.getObject("${doc.getSpace()}.Invitation")) 212: $configObj.set('from_address', 'thisisatest@localhost.localdomain') 213: $configDoc.saveAsAuthor() 214: $config.clear() 215: #loadInvitationConfig($config, 'HopefullyNonexistantSpace') 216: #if($config.get('from_address') != 'thisisatest@localhost.localdomain') 217: {{error}}altering config parameter failed.{{/error}} 218: #end 219: #end 220: #end 221: #set($configDoc = $xwiki.getDocumentAsAuthor("${doc.getSpace()}.InvitationConfig")) 222: #if(!$configDoc.isNew()) 223: $configDoc.deleteAsAuthor() 224: #end 225: #end 226: ## 227: #** 228: * Load mail from mail containing document. 229: * 230: * $config (Map<String, String>) will be used to get the name of the email class. 231: * 232: * $emailContainer (Document) the document to get the email from. 233: * 234: * $mail (Map<String, XObject>) will be populated with email message XObjects by their messageID. 235: *### 236: #macro(loadInvitationMail, $config, $emailContainer, $mail) 237: ## If this doesn't already exist, it's created. 238: #if($emailContainer.isNew()) 239: #set($emailContainerContent = '{{velo' + 'city}}{{info}}$msg.get("xe.invitation.internalDocument", ["' 240: + "$config.get('emailContainer')" + '"]){{/info}}{{/velo' + 'city}}') 241: #set($discard = $emailContainer.setContent($emailContainerContent)) 242: #end 243: ## 244: ## Load messages into a Map by messageID. 245: #foreach($obj in $emailContainer.getObjects($config.get('emailClass'))) 246: #set($discard = $mail.put($obj.getProperty('messageID').getValue(), $obj)) 247: #end 248: #end 249: ## 250: #** 251: * Is a guest allowed to accept an invitation? 252: * 253: * $guestActionsDoc (Document) the document which guests will use to register. 254: *### 255: #macro(canGuestAcceptInvitation, $guestActionsDoc) 256: #set($out = 'true') 257: #if(!$xwiki.hasAccessLevel('register', 'XWiki.XWikiGuest', 'XWiki.XWikiPreferences') 258: && !$guestActionsDoc.hasProgrammingRights()) 259: ## 260: #set($out = 'false') 261: #end 262: $out## 263: #end 264: ## 265: #** 266: * Get the action taken by the user. 267: * This will interpret actions taken using displayActionConfirmationForm 268: * 269: * $parameterMap (Map<String, String>) the parameter map gotten by calling getParameterMap on the servlet request. 270: * 271: * $actionOutList (List<String>) will be populated with a single value (the action) 272: *### 273: #macro(getUserAction, $parameterMap, $actionOutList) 274: #set($actionInternal = 0) 275: #foreach($param in $parameterMap.keySet()) 276: #if($param.indexOf('doAction_') != -1) 277: ## Strip 'doAction_' 278: #set($actionInternal = $param.substring(9)) 279: #end 280: #end 281: #if($actionInternal != 0) 282: #set($discard = $actionOutList.add($actionInternal)) 283: #end 284: #end 285: ## 286: #* 287: * Display a form allowing a user to confirm doing an action. 288: * 289: * $messageIDs (List<String>) the unique IDs of the invitations to act upon. 290: * 291: * $action (String) the action to do. 292: * 293: * $memoLabel (String) what the memo field should be labeled. 294: * 295: * $confirmLabel (String) what the confirm button should say. 296: * 297: * $additionalParameters (Map<String, String>) these parameters will be xml escaped and placed in hidden input fields. 298: *### 299: #macro(displayActionConfirmationForm, $messageIDs, $action, $memoLabel, $confirmLabel, $additionalParameters) 300: {{html wiki=false clean=false}} 301: <div class="invitation action-confirm"> 302: <form action="$doc.getURL()" method="POST"> 303: ## 304: #foreach($id in $messageIDs) 305: <input type="hidden" name="messageID" value="$escapetool.xml($id)" /> 306: #end 307: <input type="hidden" name="confirm" value="y" /> 308: <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" /> 309: #if($additionalParameters && $additionalParameters.size() > 0) 310: #foreach($param in $additionalParameters.keySet()) 311: <input type="hidden" name="$escapetool.xml($param)" value="$escapetool.xml($additionalParameters.get($param))" /> 312: #end 313: #end 314: ## 315: <dl> 316: <dt><label for="memo">$memoLabel</label></dt> 317: <dd><input type="text" size="54" name="memo" /></dd> 318: </dl> 319: <div class="bottombuttons"> 320: <div class="buttons"> 321: <span class="buttonwrapper"> 322: <input type="submit" class="button" name="doAction_$escapetool.xml($action)" value="$confirmLabel" /> 323: </span> 324: </div> 325: </div> 326: </form> 327: </div> 328: {{/html}} 329: #end 330: ## 331: #* 332: * Set the status of a message and log the memo. 333: * 334: * $message (Xobject) the message to act on. 335: * 336: * $status (String) the status to set the message to. 337: * 338: * $memo (String) what to enter in the log. 339: *### 340: #macro(setMessageStatus, $message, $status, $memo) 341: $message.set('status', $status)## 342: #set($history = $message.getProperty('history').getValue()) 343: #set($statusWord = "#messageStatusForCode($status)") 344: ## disallow injection of \n which starts a new line or { which may be used for macros. 345: #set($log = $memo.replaceAll('\n', ' ').replaceAll('\{', '~{')) 346: #set($entry = "|$statusWord|[[$xcontext.getUser()]]|$!log") 347: #if("$!history" != '') 348: $message.set('history', "$!history$util.getNewline()$entry")## 349: #else 350: $message.set('history', $entry)## 351: #end 352: #end 353: ## 354: #* 355: * Get the last memo from the message history. 356: * 357: * $message (Xobject) the message to act on. 358: *### 359: #macro(getLastMemo, $message) 360: #set($history = "$!message.getProperty('history').getValue()") 361: #set($indexAfterLastNewline = $mathtool.add($history.lastIndexOf($util.getNewline()), 1)) 362: #if($indexAfterLastNewline < $history.length()) 363: #set($entry = "$!history.substring($indexAfterLastNewline)") 364: #set($indexAfterLastPipe = $mathtool.add($entry.lastIndexOf('|'), 1)) 365: #if($indexAfterLastPipe < $entry.length()) 366: $entry.substring($indexAfterLastPipe)## 367: #end 368: #end 369: #end 370: ## 371: #* 372: * Get the status of the current message for it's code. 373: * unsent - not sent yet. 374: * pending - sent and awating a response 375: * accepted - sent and accepted by recipient 376: * declined - sent and declined by recipient 377: * canceled - sent then canceled by sender 378: * reported - as spam (by recipient) 379: * notSpam - reported as spam and investigated (by admin) 380: * sendingFailed - failed to send message 381: * else - unknown status 382: * 383: * $status (String) the status of the message. 384: *### 385: #macro(messageStatusForCode, $status) 386: #if($status == 'unsent') 387: $msg.get('xe.invitation.messageStatus.unsent')## 388: #elseif($status == 'pending') 389: $msg.get('xe.invitation.messageStatus.pending')## 390: #elseif($status == 'accepted') 391: $msg.get('xe.invitation.messageStatus.accepted')## 392: #elseif($status == 'declined') 393: $msg.get('xe.invitation.messageStatus.declined')## 394: #elseif($status == 'canceled') 395: $msg.get('xe.invitation.messageStatus.canceled')## 396: #elseif($status == 'reported') 397: $msg.get('xe.invitation.messageStatus.reported')## 398: #elseif($status == 'notSpam') 399: $msg.get('xe.invitation.messageStatus.investigated')## 400: #elseif($status == 'sendingFailed') 401: $msg.get('xe.invitation.messageStatus.sendingFailed')## 402: #else 403: $msg.get('xe.invitation.messageStatus.unknown', [$escapetool.xml($status)])## 404: #end 405: #end 406: {{/velocity}}