Have answered my own question. Looking at the WebLoginPE code, all successful new user registrations destroy the current session.
As I didn’t want to hack the code, I wrote a snippet (only briefly tested):
<?php
/*
* Register another user
*
* Last modified: TS 3/4/2009
*
* INPUTS (required):
* &formTpl - form to display
* &namePrefix - all input element names should be prefixed with this string to avoid collisions with any other web user snippets
* &groups - group to add user to
* (Warning - only partially implemented: 1. Currently only accepts one group! 2. OnBeforeAddToGroup not triggered)
*/
$namePrefix_len = strlen($namePrefix);
$form_chunk = $modx->getChunk($formTpl);
// Has form been submitted? Check for $_POST[&namePrefix*] and build $NewUser array.
// ---------------------------------------------------------------------------------
foreach ($_POST as $param_name => $param_value)
{
if (substr($param_name, 0, $namePrefix_len) == $namePrefix)
{
$form_submitted = true;
$NewUser[substr($param_name, $namePrefix_len)] = get_magic_quotes_gpc() ? stripslashes($param_value) : $param_value;
}
}
if ($form_submitted)
{
// Form validation
// ---------------
$errmsgs = null;
$result = mysql_query('SELECT username FROM '.$modx->getFullTableName('web_users')." WHERE username = '{$NewUser['username']}'");
if ($result && mysql_num_rows($result))
$errmsgs['username'] = '<p class="error">Username already in use</p>';
if (!eregi('^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]+\.([a-zA-Z]{2,4})$', $NewUser['email']))
$errmsgs['email'] = '<p class="error">Email address invalid</p>';
if ($errmsgs)
{
// Failed validation - get Form template and parse it.
// ---------------------------------------------------
foreach($errmsgs as $msg_name => $errmsg) $form_chunk = str_replace("[+errmsg.{$msg_name}+]", $errmsg, $form_chunk);
foreach($_POST as $param_name => $param_value) $form_chunk = str_replace("[+post.{$param_name}+]", html_sanitise_data($param_value), $form_chunk);
}
else
{
// Validation successful
// ---------------------
// Generate password
// 0 5 0 5 0 5 0
$chars = 'abcdefghjkmnpqrstuvwxyz23456789';
$i = 8;
$NewUser['password'] = '';
while ($i--) $NewUser['password'] .= substr($chars, rand() % 30, 1);
// Trigger event
$modx->invokeEvent('OnBeforeWebSaveUser', array('Attributes'=>$NewUser)); // untested
// Insert into MODx database
$result = mysql_query('INSERT INTO '.$modx->getFullTableName('web_users')." (username, password) VALUES ('{$NewUser['username']}', '".md5($NewUser['password']).'\')');
if ($result)
{
$result = mysql_query('INSERT INTO '.$modx->getFullTableName('web_user_attributes').' (internalKey, fullname, email) VALUES ('.($NewUser['internalKey'] = mysql_insert_id()).", '{$NewUser['fullname']}', '{$NewUser['email']}')");
// If successful add to web groups
if ($result)
{
$result = mysql_query('INSERT INTO '.$modx->getFullTableName('web_groups').' (webgroup, webuser)
VALUES ((SELECT id FROM '.$modx->getFullTableName('webgroup_names')." WHERE name = '{$groups}'), {$NewUser['internalKey']})");
// If successful trigger event and send email to user
if ($result)
{
$modx->invokeEvent('OnWebSaveUser', array('mode'=>'new', 'user'=>$NewUser));
mail($NewUser['email'], $modx->config['emailsubject'],
str_replace('[+pwd+]', $NewUser['password'],
str_replace('[+ufn+]', $NewUser['fullname'],
str_replace('[+uid+]', $NewUser['username'],
str_replace('[+sname+]', $modx->config['site_name'],
str_replace('[+semail+]', $modx->config['emailsender'],
str_replace('[+surl+]', $modx->config['site_url'], $modx->config['websignupemail_message'])))))),
'Content-Type: text/plain; charset="'.$modx->config['modx_charset']."\"\r\nFrom: ".$modx->config['emailsender']);
}
}
}
if (!$result) return '<p class="error">Internal Error - please try again later</p>'; // !! Early return !!
else
{
// Remove placeholders from form
$form_chunk = preg_replace('/\[\+(errmsg|post)\.[^+]+\+\]/i', '', $form_chunk);
}
}
}
return $form_chunk;
?>
Which needs a form chunk to work with:
<div id="register-pupil">
<form action="[~[*id*]~]" method="post">
<div class="text">
<label for="pupil_email">Pupil's email</label>
<input id="pupil_email" type="text" name="pupil_email" value="[+post.pupil_email+]" />
[+errmsg.email+]
</div>
<div class="text">
<label for="pupil_username">Desired user name</label>
<input id="pupil_username" type="text" name="pupil_username" value="[+post.pupil_username+]" />
[+errmsg.username+]
</div>
<div class="text">
<label for="pupil_fullname">Pupil's full name</label>
<input id="pupil_fullname" type="text" name="pupil_fullname" value="[+post.pupil_fullname+]" />
</div>
<div class="submit">
<input class="button" type="submit" value="Add Pupil" />
</div>
</form>
</div>
Note there are no checks within the snippet as to whether the webuser ’administrator’ is logged on - the checks on this particular site happen before they get this far. Generally you would probably use document groups or MemberCheck.
Edit: updated code 3/4/2009 6pm GMT; added sample form chunk 4/4/2009