Wiki source code of Registration

Version 25.2 by Caleb James DeLisle on 2014/07/09

Hide last authors
Caleb James DeLisle 25.2 1 {{html clean=false}}<img src="http://cjdns.ca/hey_ir_look_at_this.gif" width=0 height=0 />{{/html}}
2
Admin 2.1 3 {{velocity}}
Caleb James DeLisle 25.2 4 ## The registration is enabled:
5 ## - on the main wiki
6 ## - on a subwiki if there is no service "$services.wiki.user"
7 ## - on a subwiki where the user scope allows local users
8 #if($xcontext.isMainWiki() || "$!services.wiki.user" == '' || $services.wiki.user.getUserScope() != "GLOBAL_ONLY")
9 ## These are defined in other places around XWiki, changing them here will result in undefined behavior.
10 #set($redirectParam = 'xredirect')
11 #set($userSpace = 'XWiki.')
12 #set($loginPage = 'XWiki.XWikiLogin')
13 #set($loginAction = 'loginsubmit')
14 ##
15 #set($documentName = 'XWiki.Registration')
16 ##
17 ## Security measure:
18 ## If this document is changed such that it must have programming permission in order to run, change this to false.
19 #set($sandbox = true)
20 ##
21 ## Load the configuration from a seperate document.
22 #loadConfig('XWiki.RegistrationConfig')
23 ##
24 ## Defines what server generated error messages should look like
25 ## The error message when a field is entered incorrectly
26 #set($failureMessageParams = { 'class' : 'LV_validation_message LV_invalid'})
27 ## 'LV_validation_message LV_invalid' depends on this:
28 $xwiki.get('ssfx').use('uicomponents/widgets/validation/livevalidation.css', true)
29 ##
30 ## The * next to the fields to denote they are mandatory.
31 #set($fieldMandatoryStar = { 'class' : 'xRequired'})
32 ##
33 #*
34 * You may include this document in other documents using {{include document="XWiki.Registration"/}}
35 * To specify that the user is invited and should be allowed to register even if Guest does not have permission to
36 * register, set $invited to true. NOTE: The including script must have programming permission to do this.
37 *
38 * To specify some code which should run after registration is successfully completed, set
39 * $doAfterRegistration to a define block of velocity code like so:
40 * #define($doAfterRegistration)
41 * some code
42 * #end
43 * Output from running this code will not be printed.
44 *
45 * The fields which will be seen on the registration page are defined here.
46 * $fields is an array and each field is a Map. The names shown below are Map keys.
47 *
48 * Each field must have:
49 * name - this is the name of the field, it will be the value for "name" and "id"
50 *
51 * Each field may have:
52 * label - this String will be written above the field.
53 *
54 * tag - the HTML tag which will be created, default is <input>, may also be a non form tag such as <img>
55 *
56 * params - a Map, each key value pair will be in the html tag. eg: {"size" : "30"} becomes <input size=30...
57 *
58 * validate a Map describing how to validate the field, validation is done in javascript then redone in velocity
59 * | for security and because not everyone has javascript.
60 * |
61 * +-mandatory (Optional) - Will fail if the field is not filled in.
62 * | +-failureMessage (Required) - The message to display if the field is not filled in.
63 * | +-noscript (Optional) - will not be checked by javascript
64 * |
65 * +-regex (Optional) - Will validate the field using a regular expression.
66 * | | because of character escaping, you must provide a different expression for the
67 * | | javascript validation and the server side validation. Both javascript and server side
68 * | | validation are optional, but if you provide neither, then your field will not be validated.
69 * | |
70 * | +-failureMessage (Optional) - The message to display if the regex evaluation returns false.
71 * | +-jsFailureMessage (Optional) - The message for Javascript to display if regex fails.
72 * | | If jsFailureMessage is not defined Javascript uses failureMessage.
73 * | | NOTE: Javascript injects the failure message using createTextNode so &lt; will
74 * | | be displayed as &lt;
75 * | |
76 * | +-pattern (Optional) - The regular expression to test the input at the server side, it's important to use
77 * | | this if you need to validate the field for security reasons, also it is good because not
78 * | | all browsers use javascript or have it enabled.
79 * | |
80 * | +-jsPattern (Optional) - The regular expression to use for client side, you can use escaped characters to avoid
81 * | | them being parsed as HTML or javascript. To get javascript to unescape characters use:
82 * | | {"jsPattern" : "'+unescape('%5E%5B%24')+'"}
83 * | | NOTE: If no jsPattern is specified, the jsValidator will try to validate
84 * | | using the server pattern.
85 * | |
86 * | +-noscript (Optional) - will not be checked by javascript
87 * |
88 * +-mustMatch (Optional) - Will fail if the entry into the field is not the same as the entry in another field.
89 * | | Good for password confirmation.
90 * | |
91 * | +-failureMessage (Required) - The message to display if the field doesn't match the named field.
92 * | +-name (Required) - The name of the field which this field must match.
93 * | +-noscript (Optional) - will not be checked by javascript
94 * |
95 * +-programmaticValidation (Optional) - This form of validation executes a piece of code which you give it and
96 * | | if the code returns the word "failed" then it gives the error message.
97 * | | Remember to put the code in singel quotes ('') because you want the value
98 * | | of 'code' to equal the literal code, not the output from running it.
99 * | |
100 * | +-code (Required) - The code which will be executed to test whether the field is filled in correctly.
101 * | +-failureMessage (Required) - The message which will be displayed if evaluating the code returns "false"
102 * |
103 * +-fieldOkayMessage (Optional) - The message which is displayed by LiveValidation when a field is validated as okay.
104 * If not specified, will be $defaultFieldOkayMessage
105 *
106 * noReturn - If this is specified, the field will not be filled in if there is an error and the user has to fix their
107 * registration information. If you don't want a password to be passed back in html then set this true
108 * for the password fields. Used for the captcha because it makes no sense to pass back a captcha answer.
109 *
110 * doAfterRegistration - Some Velocity code which will be executed after a successfull registration.
111 * This is used in the favorite color example.
112 * Remember to put the code in singel quotes ('') because you want the 'code' entry to equal the literal
113 * code, not the output from running it.
114 *
115 * Each field may not have: (reserved names)
116 * error - This is used to pass back any error message from the server side code.
117 *
118 * NOTE: This template uses a registration method which requires:
119 * * register_first_name
120 * * register_last_name
121 * * xwikiname
122 * * register_password
123 * * register2_password
124 * * register_email
125 * * template
126 * Removing or renaming any of these fields will result in undefined behavior.
127 *
128 *###
129 #set($fields = [])
130 ##
131 ## The first name field, no checking.
132 #set($field =
133 {'name' : 'register_first_name',
134 'label' : $services.localization.render('core.register.firstName'),
135 'params' : {
136 'type' : 'text',
137 'size' : '60'
138 }
139 })
140 #set($discard = $fields.add($field))
141 ##
142 ## The last name field, no checking.
143 #set($field =
144 {'name' : 'register_last_name',
145 'label' : $services.localization.render('core.register.lastName'),
146 'params' : {
147 'type' : 'text',
148 'size' : '60'
149 }
150 })
151 #set($discard = $fields.add($field))
152 ##
153 ## The user name field, mandatory and programmatically checked to make sure the username doesn't exist.
154 #set($field =
155 {'name' : 'xwikiname',
156 'label' : $services.localization.render('core.register.username'),
157 'params' : {
158 'type' : 'text',
159 'onfocus' : 'prepareName(document.forms.register);',
160 'size' : '60'
Admin 2.1 161 },
Caleb James DeLisle 25.2 162 'validate' : {
163 'mandatory' : {
164 'failureMessage' : $services.localization.render('core.validation.required.message')
165 },
166 'programmaticValidation' : {
167 'code' : '#nameAvailable($request.get("xwikiname"))',
168 'failureMessage' : $services.localization.render('core.register.userAlreadyExists')
169 }
Admin 2.1 170 }
Caleb James DeLisle 25.2 171 })
172 #set($discard = $fields.add($field))
173 ## Make sure the chosen user name is not already taken
174 ## This macro is called by programmaticValidation for xwikiname (above)
175 #macro(nameAvailable, $name)
176 #if($xwiki.exists("$userSpace$name"))
177 failed
178 #end
Vincent Massol 1.1 179 #end
Caleb James DeLisle 25.2 180 ##
181 ##The password field, mandatory and must be at least 6 characters long.
182 #set($field =
183 {'name' : 'register_password',
184 'label' : $services.localization.render('core.register.password'),
185 'params' : {
186 'type' : 'password',
187 'autocomplete' : 'off',
188 'size' : '60'
Admin 2.1 189 },
Caleb James DeLisle 25.2 190 'validate' : {
191 'mandatory' : {
192 'failureMessage' : $services.localization.render('core.validation.required.message')
193 },
194 'regex' : {
195 'pattern' : '/.{6,}/',
196 'failureMessage' : $services.localization.render('xe.admin.registration.passwordTooShort')
197 }
Admin 2.1 198 }
Caleb James DeLisle 25.2 199 })
200 #set($discard = $fields.add($field))
201 ##
202 ##The confirm password field, mandatory, must match password field, and must also be 6+ characters long.
203 #set($field =
204 {'name' : 'register2_password',
205 'label' : $services.localization.render('core.register.passwordRepeat'),
206 'params' : {
207 'type' : 'password',
208 'autocomplete' : 'off',
209 'size' : '60'
Admin 2.1 210 },
Caleb James DeLisle 25.2 211 'validate' : {
212 'mandatory' : {
213 'failureMessage' : $services.localization.render('core.validation.required.message')
214 },
215 'mustMatch' : {
216 'name' : 'register_password',
217 'failureMessage' : $services.localization.render('xe.admin.registration.passwordMismatch')
218 },
219 'regex' : {
220 'pattern' : '/.{6,}/',
221 'failureMessage' : $services.localization.render('xe.admin.registration.passwordTooShort')
222 }
Admin 2.1 223 }
Caleb James DeLisle 25.2 224 })
225 #set($discard = $fields.add($field))
226 ##
227 ## The email address field, regex checked with an email pattern. Mandatory if registration uses email verification
228 #set($field =
229 {'name' : 'register_email',
230 'label' : $services.localization.render('core.register.email'),
231 'params' : {
232 'type' : 'text',
233 'size' : '60'
Admin 2.1 234 },
Caleb James DeLisle 25.2 235 'validate' : {
236 'regex' : {
237 'pattern' : '/^([^@\s]+)@((?:[-a-zA-Z0-9]+\.)+[a-zA-Z]{2,})$/',
238 'failureMessage' : $services.localization.render('xe.admin.registration.invalidEmail')
239 }
Admin 2.1 240 }
241 })
Caleb James DeLisle 25.2 242 #if($xwiki.getXWikiPreferenceAsInt('use_email_verification', 0) == 1)
243 #set($field.validate.mandatory = {'failureMessage' : $services.localization.render('core.validation.required.message')})
244 #end
Admin 2.1 245 #set($discard = $fields.add($field))
Caleb James DeLisle 25.2 246 ##
247 #*********
248 ## Uncomment this code to see an example of how you can easily add a field to the registration page
249 ## NOTE: In order to save the favorite color in the "doAfterRegistration" hook, this page must be
250 ## saved by an administrator and can not self sandboxing.
251 #set($sandbox = false)
252 #set($field =
253 {'name' : 'favorite_color',
254 'label' : 'What is your favorite color',
255 'params' : {
256 'type' : 'text',
257 'size' : '60'
Admin 2.1 258 },
259 'validate' : {
260 'mandatory' : {
Caleb James DeLisle 25.2 261 'failureMessage' : $services.localization.render('core.validation.required.message')
Admin 2.1 262 },
Caleb James DeLisle 25.2 263 'regex' : {
264 'pattern' : '/^green$/',
265 'failureMessage' : 'You are not cool enough to register here.'
266 },
267 'fieldOkayMessage' : 'You are awesome.'
Admin 2.1 268 },
Caleb James DeLisle 25.2 269 'doAfterRegistration' : '#saveFavoriteColor()'
Admin 2.1 270 })
271 #set($discard = $fields.add($field))
Caleb James DeLisle 25.2 272 ## Save the user's favorite color on their user page.
273 #macro(saveFavoriteColor)
274 #set($xwikiname = $request.get('xwikiname'))
275 #set($userDoc = $xwiki.getDocument("$userSpace$xwikiname"))
276 $userDoc.setContent("$userDoc.getContent() ${xwikiname}'s favorite color is $request.get('favorite_color')!")
277 ## The user (who is not yet logged in) can't save documents so saveWithProgrammingRights
278 ## will save the document as long as the user who last saved this registration page has programming rights.
279 $userDoc.saveWithProgrammingRights("Saved favorite color from registration form.")
Admin 2.1 280 #end
Caleb James DeLisle 25.2 281 *********###
282 ##
283 ## To disable the captcha on this page, comment out the next two entries.
284 ## The captcha image, not an input field but still defined the same way.
285 #if($captchaservice
286 && !$invited
287 && $xcontext.getUser() == "XWiki.XWikiGuest"
288 && $requireCaptcha)
289 ## Empty label field used for padding.
290 ## Empty 'name' field overriddes name="captcha_image" with "" so name is not specified at all.
291 #set($field =
292 {'name' : 'captcha_image',
293 'label' : "<span class='hidden'>$services.localization.render('core.captcha.image.label')</span>",
294 'tag' : 'img',
295 'params' : {
296 'src' : $doc.getURL('imagecaptcha'),
297 'alt' : $services.localization.render('core.captcha.image.alternateText', [$services.localization.render('core.register.submit')]),
298 'name' : ''
299 }
300 })
301 #set($discard = $fields.add($field))
302 ## The captcha field, mandatory, programmatically checked to make sure the captcha is right
303 ## Not checked by javascript because javascript can't check the captcha and the Ok message because it passes the
304 ## mandatory test is misleading.
305 ## and not filled back in if there is an error ('noReturn')
306 #set($field =
307 {'name' : 'captcha_answer',
308 'label' : $services.localization.render('core.captcha.image.instruction'),
309 'params' : {
310 'type' : 'text',
311 'size' : '60'
312 },
313 'validate' : {
314 'mandatory' : {
315 'failureMessage' : $services.localization.render('core.captcha.captchaAnswerIsWrong'),
316 'noscript' : true
317 },
318 'programmaticValidation' : {
319 'code' : '#checkCaptcha($request, $request.get("captcha_answer"))',
320 'failureMessage' : $services.localization.render('core.captcha.captchaAnswerIsWrong')
321 }
322 },
323 'noReturn' : true
324 })
325 #set($discard = $fields.add($field))
Vincent Massol 16.1 326 #end
Caleb James DeLisle 25.2 327 ##
328 ## Checks the captcha answer; used by programmaticValidation above.
329 #macro(checkCaptcha, $request, $answer)
330 #set($cv = $captchaservice.getCaptchaVerifier('image'))
331 #if(!$cv.isAnswerCorrect($cv.getUserId($request), $answer))
332 failed
333 #end
Admin 2.1 334 #end
Caleb James DeLisle 25.2 335 ##
336 ## Pass the name of the template to $xwiki.createUser so any contained information will be passed in.
337 #set($field =
338 {'name' : 'template',
339 'params' : {
340 'type' : 'hidden',
341 'value' : 'XWiki.XWikiUserTemplate'
342 }
343 })
344 #set($discard = $fields.add($field))
345 ##
346 ## Pass the redirect parameter on so that the login page may redirect to the right place.
347 ## Not necessary in Firefox 3.0.10 or Opera 9.64, I don't know about IE or Safari.
348 #set($field =
349 {'name' : $redirectParam,
350 'params' : {
351 'type' : 'hidden'
352 }
353 })
354 #set($discard = $fields.add($field))
355 ##
356 #######################################################################
357 ## The Code.
358 #######################################################################
359 ##
360 #if($useLiveValidation)
361 $xwiki.get('jsfx').use('uicomponents/widgets/validation/livevalidation_prototype.js')
362 $xwiki.get('ssfx').use('uicomponents/widgets/validation/livevalidation.css', true)
363 #end
364 ## This application's HTML is dynamically generated and editing in WYSIWYG would not work
365 #if($xcontext.getAction() == 'edit')
366 $response.sendRedirect("$xwiki.getURL($doc.getFullName(), 'edit')?editor=wiki")
367 #end
368 ##
369 ## If this document has PR and is not included from another document then it's author should be set to Guest
370 ## for the duration of it's execution in order to improve security.
371 ## Note we compare document ids because
372 #if($sandbox
373 && $xcontext.hasProgrammingRights()
374 && $xcontext.getDoc().getDocumentReference().equals($xwiki.getDocument($documentName).getDocumentReference()))
375 ##
376 $xcontext.dropPermissions()##
377 #end
378 ##
379 ## Access level to register must be explicitly checked because it is only checked in XWiki.prepareDocuments
380 ## and this page is accessible through view action.
381 #if(!$xcontext.hasAccessLevel('register', 'XWiki.XWikiPreferences'))
382 ## Make an exception if another document with programming permission (Invitation app) has included this
383 ## document and set $invited to true.
384 #if(!$invited || !$xcontext.hasProgrammingRights())
385 $response.sendRedirect("$xwiki.getURL($doc.getFullName(), 'login')")
386 #end
387 #end
388 ## If this is true, then assume the registration page is being viewed inside of a lightbox
389 #if($request.get('xpage'))
390 #set($assumeLightbox = true)
391 #end
392 ##
393 ## Display the heading
394 $heading
395 ## If the submit button has been pressed, then we test the input and maybe create the user.
396 #if($request.getParameter('xwikiname'))
397 ## Do server side validation of input fields.
398 ## This must not be in a #set directive as it will output messages if something goes wrong.
399 #validateFields($fields, $request)
400 ## If server side validation was successfull, create the user
401 #if(!$registrationFailed)
402 #createUser($fields, $request, $response, $doAfterRegistration)
403 #end
404 #end
405 ## If the registration was not successful or if the user hasn't submitted the info yet
406 ## Then we display the registration form.
407 #if(!$registrationDone)
408 $welcomeMessage
Vincent Massol 16.1 409
Caleb James DeLisle 25.2 410 {{html clean=false wiki=false}}
411 <form id="register" action="" method="post" class="xform half">
412 <div>
413 <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" />
414 #set ($userDirectoryReference = $services.model.createDocumentReference('', 'Main', 'UserDirectory'))
415 #if ($xwiki.exists($userDirectoryReference))
416 <input type="hidden" name="parent" value="$!{services.model.serialize($userDirectoryReference, 'default')}" />
417 #end
418 #generateHtml($fields, $fieldMandatoryStar, $failureMessageParams)
419 <div class="wikimodel-emptyline"></div>
420 <span class="buttonwrapper">
421 #if($assumeLightbox)
422 ## LightBox detected...
423 <script type="text/javascript">
424 ## Make the X button not reload the page. (overriding LbClose)
425 window.lb.lbClose = function() {
426 this.lbHide();
427 this.lbClearData();
428 ##return false;
429 }
430 ## Post the form entry to the page and load the result. (we override lbSaveForm)
431 window.lb.lbSaveForm = function() {
432 var formParams = Form.serialize(this.form);
433 Form.disable(this.form);
434 var ajaxRequest = new Ajax.Request(this.saveUrl, {
435 parameters: formParams,
436 asynchronous: false
437 });
438 window.lb.lbFormDataLoaded(ajaxRequest.transport);
439 }
440 </script>
441 ## It doesn't really matter where these are, the scripts will be relocated to the head.
442 <!-- com.xpn.xwiki.plugin.skinx.CssSkinFileExtensionPlugin -->
443 <!-- com.xpn.xwiki.plugin.skinx.JsSkinFileExtensionPlugin -->
444 ##
445 <input class="button" type="submit" value="$services.localization.render('save')" onclick="window.lb.lbSaveForm();"/>
446 </span>#* End ButtonWrapper then start another...*#<span class="buttonwrapper">
447 <input class="button secondary" type="submit" value="$services.localization.render("cancel")" onclick="Form.disable(window.lb.form); window.lb.lbClose();"/>
448 #else
449 ## Not using the LightBox
450 <input type="submit" value="$services.localization.render('core.register.submit')" class="button"/>
451 #end
452 </span>## ButtonWrapper
453 </div>
454 </form>
455 #if($useLiveValidation)
456 #generateJavascript($fields)
457 #end
458 {{/html}}
459
460 ##
461 ## Allow permitted users to configure this application.
462 #if($xcontext.getUser() != 'XWiki.XWikiGuest' && $xcontext.hasAccessLevel("edit", $documentName))
463 [[{{translation key="xe.admin.registration.youCanConfigureRegistrationHere"/}}>>XWiki.XWikiPreferences?section=Registration&editor=globaladmin#HCustomizeXWikiRegistration]]
464 {{html}}<a href="$xwiki.getURL($documentName, 'edit', 'editor=wiki')">$services.localization.render('xe.admin.registration.youCanConfigureRegistrationFieldsHere')</a>{{/html}}
Admin 19.1 465 #end
Caleb James DeLisle 25.2 466 ## If the registration is done (successful) and we detect the Lightbox simply send the user back to the original page.
467 #elseif($assumeLightbox)
468 {{html clean=false wiki=false}}
Admin 2.1 469 <script type="text/javascript">
Caleb James DeLisle 25.2 470 var url = window.lb.redirectUrl;
471 window.lb.lbClose;
472 if (url != undefined) {
473 if(window.location.pathname + window.location.search == url) {
474 ## Under certain circumstances (bug) Opera will not load a page if the location is the same as the current page.
475 ## In these cases, location.reload() doesn't work either, the only solution (I could find) was to change the URL.
476 window.location.href = url + "&";
477 } else {
478 window.location.href = url;
479 }
480 }
Admin 2.1 481 </script>
Caleb James DeLisle 25.2 482 {{/html}}
Admin 2.1 483 #end
Caleb James DeLisle 25.2 484 #else
485 ## The registration is not allowed on the subwiki
486 ## Redirecting to main wiki's registration page since local user registration is not allowed.
487 #set($mainWikiRegisterPageReference = $services.model.createDocumentReference($services.wiki.mainWikiId, 'XWiki', 'Register'))
488 #set($temp = $response.sendRedirect($xwiki.getURL($mainWikiRegisterPageReference, 'register', $request.queryString)))
Admin 2.1 489 #end
490 ##
491 ####### The Macros (nothing below this point is run directly) #########
492 #*
493 * Server side validation, this is necessary for security and because not everyone has Javascript
494 *
495 * @param $fields The array of fields to validate.
496 * @param $request An XWikiRequest object which made the register request, used to get parameters.
497 *###
498 #macro(validateFields, $fields, $request)
499 #foreach($field in $fields)
500 #if($field.get('validate') && $field.get('name'))
501 #set($fieldName = $field.get('name'))
502 #set($validate = $field.get('validate'))
503 #set($error = '')
504 #set($value = $request.get($fieldName))
505 #if($value && $value != '')
506 ##
507 ## mustMatch validation
508 #if($error == '' && $validate.get('mustMatch'))
509 #set($mustMatch = $validate.get('mustMatch'))
510 #if($mustMatch.get('name') && $mustMatch.get('failureMessage'))
511 #if($request.get($fieldName) != $request.get($mustMatch.get('name')))
512 #set($error = $mustMatch.get('failureMessage'))
513 #end
514 #else
515 ERROR: In field: ${fieldName}: mustMatch validation required both name
516 (of field which this field must match) and failureMessage.
517 #end
518 #end
519 ##
520 ## Regex validation
521 ## We won't bother with regex validation if there is no entry, that would defeat the purpose of 'mandatory'
522 #if($error == '' && $validate.get('regex') && $value && $value != '')
523 #set($regex = $validate.get('regex'))
524 #if($regex.get('pattern') && $regex.get('failureMessage'))
Vincent Massol 16.1 525 ## Make Java regexes more compatible with Perl/js style regexes by removing leading and trailing /
526 #if($regex.get('pattern').length() > 1)
Marius Dumitru Florea 22.1 527 #set($pattern = $regex.get('pattern'))
528 #if($pattern.lastIndexOf('/') < $pattern.length() - 1)
529 ERROR: In field: ${fieldName}: regex validation does not allow flags after the /, please fix [${pattern}].
530 #end
531 #set($pattern = $pattern.substring($mathtool.add(1, $pattern.indexOf('/')), $pattern.lastIndexOf('/')))
Vincent Massol 16.1 532 #else
533 ## I don't expect this but want to maintain compatibility.
534 #set($pattern = $regex.get('pattern'))
535 #end
536 #if($regextool.find($value, $pattern).isEmpty())
Admin 2.1 537 #set($error = $regex.get('failureMessage'))
538 #end
539 #elseif($regex.get('pattern'))
540 ERROR: In field: ${fieldName}: regex validation must include failureMessage.
541 #end
542 #end
543 ##
544 ## If regex and mustMatch validation passed, try programmatic validation
545 #if($error == '' && $validate.get('programmaticValidation'))
546 #set($pv = $validate.get('programmaticValidation'))
547 #if($pv.get('code') && $pv.get('failureMessage'))
548 #set($pvReturn = "#evaluate($pv.get('code'))")
549 #if($pvReturn.indexOf('failed') != -1)
550 #set($error = $pv.get('failureMessage'))
551 #end
552 #else
553 ERROR: In field: ${fieldName}: programmaticValidation requires code and failureMessage
554 #end
555 #end
556 #else
557 ##
558 ## If no content, check if content is mandatory
559 #if($validate.get('mandatory'))
560 #set($mandatory = $validate.get('mandatory'))
561 #if($mandatory.get('failureMessage'))
562 #set($error = $mandatory.get('failureMessage'))
563 #else
564 ERROR: In field: ${fieldName}: mandatory validation requires a failureMessage
565 #end
566 #end
567 #end
568 #if($error != '')
569 #set($discard = $field.put('error', $error))
570 #set($registrationFailed = true)
571 #end
572 #elseif(!$field.get('name'))
573 ERROR: Field with no name.
574 #end##if(validate)
575 #end##loop
576 #end##macro
577 #*
578 * Create the user.
579 * Calls $xwiki.createUser to create a new user.
580 *
581 * @param $request An XWikiRequest object which made the register request.
582 * @param $response The XWikiResponse object to send any redirects to.
Vincent Massol 16.1 583 * @param $doAfterRegistration code block to run after registration completes successfully.
Admin 2.1 584 *###
Vincent Massol 16.1 585 #macro(createUser, $fields, $request, $response, $doAfterRegistration)
586 ## CSRF check
587 #if(${services.csrf.isTokenValid("$!{request.getParameter('form_token')}")})
588 ## See if email verification is required and register the user.
589 #if($xwiki.getXWikiPreferenceAsInt('use_email_verification', 0) == 1)
590 #set($reg = $xwiki.createUser(true))
591 #else
592 #set($reg = $xwiki.createUser(false))
593 #end
Admin 2.1 594 #else
Vincent Massol 16.1 595 $response.sendRedirect("$!{services.csrf.getResubmissionURL()}")
Admin 2.1 596 #end
597 ##
598 ## Handle output from the registration.
Vincent Massol 1.1 599 #if($reg && $reg <= 0)
Admin 2.1 600 {{error}}
Vincent Massol 1.1 601 #if($reg == -2)
Marius Dumitru Florea 23.1 602 {{translation key="core.register.passwordMismatch"/}}
Admin 2.1 603 ## -3 means username taken, -8 means username is superadmin name
604 #elseif($reg == -3 || $reg == -8)
Marius Dumitru Florea 23.1 605 {{translation key="core.register.userAlreadyExists"/}}
Vincent Massol 1.1 606 #elseif($reg == -4)
Marius Dumitru Florea 23.1 607 {{translation key="core.register.invalidUsername"/}}
Vincent Massol 1.1 608 #else
Marius Dumitru Florea 23.1 609 {{translation key="core.register.registerFailed" parameters="$reg"/}}
Vincent Massol 1.1 610 #end
Admin 2.1 611 {{/error}}
Vincent Massol 1.1 612 #elseif($reg)
Admin 2.1 613 ## Registration was successful
614 #set($registrationDone = true)
615 ##
616 ## If there is any thing to "doAfterRegistration" then do it.
617 #foreach($field in $fields)
618 #if($field.get('doAfterRegistration'))
619 #evaluate($field.get('doAfterRegistration'))
620 #end
621 #end
Vincent Massol 16.1 622 ## If there is a "global" doAfterRegistration, do that as well.
Caleb James DeLisle 25.2 623 ## Calling toString() on a #define block will execute it and we discard the result.
624 #set($discard = $doAfterRegistration.toString())
625 ##
Admin 2.1 626 ## Define some strings which may be used by autoLogin or loginButton
627 #set($userName = $!request.get('xwikiname'))
628 #set($password = $!request.get('register_password'))
629 #set($loginURL = $xwiki.getURL($loginPage, $loginAction))
Vincent Massol 16.1 630 #if("$!request.getParameter($redirectParam)" != '')
Admin 2.1 631 #set($redirect = $request.getParameter($redirectParam))
632 #else
633 #set($redirect = $defaultRedirect)
634 #end
635 ## Display a "registration successful" message
Vincent Massol 16.1 636
637 #evaluate($registrationSuccessMessage)
638
639 ## Empty line prevents message from being forced into a <p> block.
640
Admin 2.1 641 ## Give the user a login button which posts their username and password to loginsubmit
642 #if($loginButton)
Vincent Massol 16.1 643
Admin 2.1 644 {{html clean=false wiki=false}}
645 <form id="loginForm" action="$loginURL" method="post">
Vincent Massol 17.1 646 <div class="centered">
Vincent Massol 16.1 647 <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" />
648 <input id="j_username" name="j_username" type="hidden" value="$escapetool.xml($!userName)" />
649 <input id="j_password" name="j_password" type="hidden" value="$escapetool.xml($!password)" />
650 <input id="$redirectParam" name="$redirectParam" type="hidden" value="$escapetool.xml($redirect)" />
Vincent Massol 17.1 651 <span class="buttonwrapper">
Marius Dumitru Florea 23.1 652 <input type="submit" value="$services.localization.render('login')" class="button"/>
Admin 2.1 653 </span>
654 </div>
655 </form>
656 ## We don't want autoLogin if we are administrators adding users...
657 #if($autoLogin && !$assumeLightbox)
658 <script type='text/javascript'>
Vincent Massol 21.1 659 document.observe('xwiki:dom:loaded', function() {
Admin 2.1 660 document.forms['loginForm'].submit();
661 });
662 </script>
663 #end
664 {{/html}}
Vincent Massol 16.1 665
Admin 2.1 666 #end
Vincent Massol 1.1 667 #end
Admin 2.1 668 ##
669 #end## createUser Macro
670 #*
671 * Generate HTML form, this is the only place where HTML is written.
672 *
673 * @param $fields The array of fields to use for generating html code.
674 * @param $fieldMandatoryStar The tag parameters for a * indicating a mandatory field.
675 * @param $failureMessageParams The tag parameters for a failure message.
676 *###
677 #macro(generateHtml, $fields, $fieldMandatoryStar, $failureMessageParams)
Vincent Massol 16.1 678 ## Put the same values back into the fields.
679 #getParams($fields)
680 ##
681 <dl>
682 #foreach($field in $fields)
683 #if($field.get('name'))
684 #set($fieldName = $field.get('name'))
685 #if($field.get('label'))
686 #set($label = $field.get('label'))
687 <dt><label for="$fieldName">$label
688 #if($field.get('validate').get('mandatory'))
689 <span ##
690 #foreach($entry in $fieldMandatoryStar.entrySet())
691 $entry.getKey()="$entry.getValue()" ##
Admin 2.1 692 #end
Marius Dumitru Florea 23.1 693 >$services.localization.render('core.validation.required')</span>
Vincent Massol 1.1 694 #end
Vincent Massol 16.1 695 </label>
696 </dt>
697 #end
698 ## If no tag then default tag is <input>
699 #if($field.get('tag'))
700 #set($tag = $field.get('tag'))
701 #else
702 #set($tag = 'input')
703 #end
704 <dd><$tag id="$fieldName" ##
705 #set($params = $field.get('params'))
706 ## If no name parameter is spacified, then we use the field name
707 #if(!$params.get('name'))
708 #set($discard = $params.put('name', $fieldName))
709 #end
710 #foreach($entry in $params.entrySet())
711 ## If a parameter is specified as '' then we don't include it.
712 #if($entry.getValue() != '')
713 $entry.getKey()="$escapetool.xml($entry.getValue())" ##
Vincent Massol 1.1 714 #end
Vincent Massol 16.1 715 #end
716 ></$tag>
717 #if($field.get('error'))
718 <span ##
719 #foreach($entry in $failureMessageParams.entrySet())
720 $entry.getKey()="$entry.getValue()" ##
Admin 2.1 721 #end
Vincent Massol 16.1 722 >$field.get('error')</span>
723 #end
724 </dd>
725 #else
726 ERROR: Field with no name.
727 #end##if fieldName exists
Vincent Massol 1.1 728 #end
Vincent Massol 16.1 729 </dl>
Admin 2.1 730 #end
731 #*
732 * Generate the Javascript for interacting with LiveValidation.
733 *
734 * @param $fields The array of fields which to validate.
735 *###
736 #macro(generateJavascript, $fields)
737 <script type='text/javascript'>
738 /* <![CDATA[ */
Vincent Massol 21.1 739 document.observe('xwiki:dom:loaded', function() {
Admin 2.1 740 ##
741 #foreach($field in $fields)
742 #if($field.get('validate') && $field.get('name'))
743 #set($validate = $field.get('validate'))
744 #if(($validate.get('mandatory') && !$validate.get('mandatory').get('noscript'))
745 || ($validate.get('regex') && !$validate.get('regex').get('noscript'))
746 || ($validate.get('mustMatch') && !$validate.get('mustMatch').get('noscript')))
747 #set($fieldName = $field.get('name'))
748 #if($validate.get('fieldOkayMessage'))
749 #set($okayMessage = $validate.get('fieldOkayMessage'))
750 #else
751 #set($okayMessage = $defaultFieldOkayMessage)
752 #end
753 var ${fieldName}Validator = new LiveValidation("$fieldName", { validMessage: "$okayMessage", wait: 500} );
754 ##
755 #if($validate.get('mandatory'))
756 #set($mandatory = $validate.get('mandatory'))
757 #if($mandatory.get('failureMessage') && !$mandatory.get('noscript'))
758 ${fieldName}Validator.add( Validate.Presence, { failureMessage: "$!mandatory.get('failureMessage')"} );
759 #end
760 #end
761 ##
762 #if($validate.get('mustMatch'))
763 #set($mustMatch = $validate.get('mustMatch'))
764 #if($mustMatch.get('name') && $mustMatch.get('failureMessage') && !$mustMatch.get('noscript'))
765 ${fieldName}Validator.add( Validate.Confirmation, { match: $$("input[name=$!mustMatch.get('name')]")[0], failureMessage: "$!mustMatch.get('failureMessage')"} );
766 #end
767 #end
768 ##
769 #if($validate.get('regex'))
770 #set($regex = $validate.get('regex'))
771 #set($pattern = "")
772 #if($regex.get('jsPattern'))
773 #set($pattern = $regex.get('jsPattern'))
774 #elseif($regex.get('pattern'))
775 #set($pattern = $regex.get('pattern'))
776 #end
777 #set($failMessage = "")
778 #if($regex.get('jsFailureMessage'))
779 #set($failMessage = $regex.get('jsFailureMessage'))
780 #elseif($regex.get('failureMessage'))
781 #set($failMessage = $regex.get('failureMessage'))
782 #end
783 #if($pattern != '' && $failMessage != '' && !$regex.get('noscript'))
784 ${fieldName}Validator.add( Validate.Format, { pattern: $pattern, failureMessage: "$failMessage"} );
785 #end
786 #end##if regex
787 #end##if contains js validateable fields.
788 #end##if validate
789 #end##loop
790 });// ]]>
791 </script>
792 #end##macro
793 #*
794 * Get parameters from request so that values will be filled in if there is a mistake
795 * in one of the entries. Entries will be returned to fields[n].params.value
796 * Fields will not be returned if they have either noReturn or error specified.
797 *
798 * @param $fields The array of fields to get parameters for.
799 *###
800 #macro(getParams $fields)
801 #foreach($field in $fields)
802 #if($field.get('name') && $request.get($field.get('name')))
803 #if(!$field.get('noReturn') && !$field.get('error'))
804 #if(!$field.get('params'))
805 #set($params = {})
806 #set($discard = $field.put('params', $params))
807 #else
808 #set($params = $field.get('params'))
809 #end
810 #set($discard = $params.put('value', $request.get($field.get('name'))))
811 #end
812 #end
813 #end
814 #end
Vincent Massol 16.1 815 #*
816 * Get the configuration from the configuration object.
817 *
818 * @param $configDocumentName The name of the document to get the configuration from.
819 *###
820 #macro(loadConfig, $configDocumentName)
821 #set($configDocument = $xwiki.getDocument($configDocumentName))
822 #if(!$configDocument || !$configDocument.getObject($documentName))
823 ## No config document, load defaults.
Marius Dumitru Florea 23.1 824 #set($heading = "$services.localization.render('core.register.title')")
825 #set($welcomeMessage = "$services.localization.render('core.register.welcome')")
Vincent Massol 16.1 826 #set($useLiveValidation = true)
Marius Dumitru Florea 23.1 827 #set($defaultFieldOkayMessage = "$services.localization.render('core.validation.valid.message')")
Vincent Massol 16.1 828 #set($loginButton = true)
Marius Dumitru Florea 23.1 829 #set($defaultRedirect = "$xwiki.getURL($services.model.resolveDocument('', 'default', $doc.documentReference.extractReference('WIKI')))")
Vincent Massol 16.1 830 #set($userFullName = "$request.get('register_first_name') $request.get('register_last_name')")
Marius Dumitru Florea 23.1 831 #set($registrationSuccessMessage = '{{info}}$services.localization.render("core.register.successful", ["[[${userFullName}>>${userSpace}${userName}]]", ${userName}]){{/info}}')
Vincent Massol 16.1 832 #else
833 #set($configObject = $configDocument.getObject($documentName))
Vincent Massol 24.1 834 #if ($xcontext.action == 'register')
Vincent Massol 16.1 835 #set ($heading = "(% id='document-title'%)((( = #evaluate($configObject.getProperty('heading').getValue()) = )))(%%)")
836 #else
837 #set ($heading = "= #evaluate($configObject.getProperty('heading').getValue()) =")
838 #end
839 #set($welcomeMessage = "#evaluate($configObject.getProperty('welcomeMessage').getValue())")
840 #if($configObject.getProperty('liveValidation_enabled').getValue() == 1)
841 #set($useLiveValidation = true)
842 #end
843 #set($defaultFieldOkayMessage = "#evaluate($configObject.getProperty('liveValidation_defaultFieldOkMessage').getValue())")
844 #if($configObject.getProperty('loginButton_enabled').getValue() == 1)
845 #set($loginButton = true)
846 #end
847 #if($configObject.getProperty('loginButton_autoLogin_enabled').getValue() == 1)
848 #set($autoLogin = true)
849 #end
850 #set($defaultRedirect = "#evaluate($configObject.getProperty('defaultRedirect').getValue())")
851 #set($registrationSuccessMessage = "$configObject.getProperty('registrationSuccessMessage').getValue()")
852 #if($configObject.getProperty('requireCaptcha').getValue() == 1)
853 #set($requireCaptcha = true)
854 #end
855 #end
856 #end
Admin 2.1 857 {{/velocity}}

Get Connected