In response to
this thread I've been working at extending the functionality of the system module to include confirmation emails with user initiated email changes. It's been pretty straightforward except that I've come up against an object handler or database concurrency issue that I simply can't get my head around.
The bulk of the hack is in edituser.php (extract below) and is modelled on the activation process in register.php. I'm up to testing the database interaction. I haven't tested the mailer. Setting up a pending email change works and is properly reflected in the users table. Cancelling and/or activating the change produces this error.
Quote:
Warning: Insert failed in method 'cleanVars' of object 'XoopsUser' in file /class/model/write.php line 265
I can't see for the code what is different in the method I've used to update the user record. Any help, advice or pointers to tutorials would be appreciated.
// confirmed email change - Rob Stockley -----------------------------
if ($op == 'processpending'){
// get to here after form is submitted
if (!$GLOBALS['xoopsSecurity']->check()) {
redirect_header('index.php', 3, _US_NOEDITRIGHT . "<br />" . implode('<br />', $GLOBALS['xoopsSecurity']->getErrors()));
exit();
}
$uid = (!empty($_POST['uid'])) ? intval($_POST['uid']) : 0;
$pemail = (!empty($_POST['pending_email'])) ? $myts->stripSlashesGPC(trim($_POST['pending_email'])) : '';
$pwd_txt = (!empty($_POST['pwd_txt'])) ? $myts->stripSlashesGPC(trim($_POST['pwd_txt'])) : '';
// check sanity of user
if (empty($uid) || $xoopsUser->getVar('uid') != $uid) {
redirect_header('index.php', 3, _US_NOEDITRIGHT);
exit();
}
// check format of proposed email
if ($pemail == '' || ! checkEmail($pemail)) {
$errors[] = _US_INVALIDMAIL;
}
// check user password
if ($pwd_txt == '') {
$errors[] = _US_ENTERPWD;
} elseif (strcmp($xoopsUser->getVar('pass'), md5($pwd_txt)) != 0) {
$errors[] = _US_INVALIDPWD;
}
// if there were form errors display these and rerun the form.
if (count($errors) > 0) {
include $GLOBALS['xoops']->path('header.php');
echo '<div>';
foreach ($errors as $er) {
echo '<span style="color: #ff0000; font-weight: bold;">' . $er . '</span><br />';
}
echo '</div><br />';
$op = 'changeemail';
} else {
// no errors so update the user record
$pkey = substr(md5(uniqid(mt_rand(), 1)), 0, 8);
$member_handler =& xoops_gethandler('member');
$edituser =& $member_handler->getUser($uid);
$edituser->setVar('pending_email', $pemail);
$edituser->setVar('pending_key', $pkey);
if (! $member_handler->insertUser($edituser)) {
include $GLOBALS['xoops']->path('header.php');
echo $edituser->getHtmlErrors();
include $GLOBALS['xoops']->path('footer.php');
} else {
//invoke the mailer
$xoopsMailer =& xoops_getMailer();
$xoopsMailer->useMail();
$xoopsMailer->setTemplate('changeemail.tpl');
$xoopsMailer->assign('SITENAME', $xoopsConfig['sitename']);
$xoopsMailer->assign('ADMINMAIL', $xoopsConfig['adminmail']);
$xoopsMailer->assign('SITEURL', XOOPS_URL . "/");
$xoopsMailer->setToEmails(array($pemail));
$xoopsMailer->setFromEmail($xoopsConfig['adminmail']);
$xoopsMailer->setFromName($xoopsConfig['sitename']);
$xoopsMailer->setSubject(sprintf(_US_USERKEYFOR, $uname));
# if (! $xoopsMailer->send()) {
# echo _US_PMAILFAIL;
# } else {
# echo _US_PMAILSUCCESS;
# }
redirect_header('userinfo.php?uid=' . $uid, 1, _US_PROFUPDATED);
}
exit();
}
}
if ($op == 'changeemail'){
// get to here when change email button is clicked
include_once $GLOBALS['xoops']->path('header.php');
include_once $GLOBALS['xoops']->path('include/comment_constants.php');
include_once $GLOBALS['xoops']->path('include/xoopscodes.php');
$uid = $xoopsUser->getVar('uid');
echo '<a href="userinfo.php?uid=' . $uid . '">' . _US_PROFILE . '</a> <span style="font-weight:bold;">»»</span> ' . _US_CHANGEEMAIL . '<br /><br />';
$form = new XoopsThemeForm(_US_CHANGEEMAIL, 'userinfo', 'edituser.php', 'post', true);
$email = new XoopsFormLabel(_US_EMAIL, $xoopsUser->getVar('email'));
$form->addElement($email);
$pending_email = new XoopsFormText(_US_NEWEMAIL, 'pending_email', 30, 60, $xoopsUser->getVar('pending_email', 'E'));
$form->addElement($pending_email);
// inlcude password to avoid account hijacking
$pwd_text = new XoopsFormPassword(_US_PASSWORD, 'pwd_txt', 10, 32);
$form->addElement($pwd_text);
$form->addElement(new XoopsFormHidden('op', 'processpending'));
$form->addElement(new XoopsFormHidden('uid', $uid));
$form->addElement(new XoopsFormButton('', 'submit', _SUBMIT, 'submit'));
$form->display();
include $GLOBALS['xoops']->path('footer.php');
}
if ($op == 'actvemail' || $op == 'cancelpending'){
// get to here if cancel button clicked or through email link
$uid = (!empty($_GET['uid'])) ? intval($_GET['uid']) : 0;
$pkey = (!empty($_GET['pending_key'])) ? trim($_GET['pending_key']) : '';
$pemail = $xoopsUser->getVar('pending_email', 'E');
// user sanity check
if (empty($uid) || $xoopsUser->getVar('uid') != $uid) {
redirect_header('index.php', 3, _US_NOEDITRIGHT);
exit();
}
// get ready to update the user record
$member_handler =& xoops_gethandler('member');
$edituser =& $member_handler->getUser($uid);
if ($op == 'actvemail') {
// if we're being activated then check the key
if ($pkey == '' || strcmp($pkey, $xoopsUser->getVar('pending_key')) != 0) {
redirect_header('index.php', 3, _US_NOEDITRIGHT . "<br />" . implode('<br />', $GLOBALS['xoopsSecurity']->getErrors()));
exit();
}
// key was good copy pending email into primary email field
$edituser->setVar('email', $pemail);
}
// always cancel the pending email if we get to here
$edituser->setVar('pending_email', '');
$edituser->setVar('pending_key', '');
if (! $member_handler->insertUser($edituser)) {
include $GLOBALS['xoops']->path('header.php');
echo $edituser->getHtmlErrors();
include $GLOBALS['xoops']->path('footer.php');
} else {
redirect_header('userinfo.php?uid=' . $uid, 1, _US_PROFUPDATED);
}
exit();
}
// confirmed email change - Rob Stockley -----------------------------