/** * Creates, saves and sends a registration e-mail address verification code. * * Parameters passed in the $args array: * ------------------------------------- * array $args['reginfo'] An array containing a valid registration record; optional; if not set, then $args['uid'] must * be set and point to a valid registration record. * numeric $args['uid'] The uid of a valid registration record; optional; if not set, then $args['reginfo'] must be set and valid. * boolean $args['force'] Indicates that a verification code should be sent, even if the Users module configuration is * set not to verify e-mail addresses; optional; only has an effect if the current user is * an administrator. * array $args['rendererArgs'] Optional arguments to send to the Zikula_View instance while rendering the e-mail message. * * @param array $args All parameters passed to this function. * * @return bool True on success; otherwise false. * * @throws Zikula_Exception_Forbidden Thrown if the user is not logged in and does not have read access, or if the user is logged in * and does not have moderate access. */ public function sendVerificationCode($args) { // In the future, it is possible we will add a feature to allow a newly registered user to resend // a new verification code to himself after doing a login-like process with information from his // registration record, so allow not-logged-in plus READ, as well as moderator. if ((!UserUtil::isLoggedIn() && !SecurityUtil::checkPermission('Users::', '::', ACCESS_READ)) || (UserUtil::isLoggedIn() && !SecurityUtil::checkPermission('Users::', '::', ACCESS_MODERATE))) { throw new Zikula_Exception_Forbidden(); } if (isset($args['reginfo'])) { // Got a full reginfo record if (!is_array($args['reginfo'])) { $this->registerError(LogUtil::getErrorMsgArgs()); return false; } $reginfo = $args['reginfo']; if (!$reginfo || !is_array($reginfo) || !isset($reginfo['uid']) || !is_numeric($reginfo['uid'])) { $this->registerError(LogUtil::getErrorMsgArgs()); return false; } } elseif (!isset($args['uid']) || !is_numeric($args['uid']) || ((int)$args['uid'] != $args['uid'])) { $this->registerError(LogUtil::getErrorMsgArgs()); return false; } else { // Got just a uid. $reginfo = UserUtil::getVars($args['uid'], false, 'uid', true); if (!$reginfo || empty($reginfo)) { $this->registerError($this->__f('Error! Unable to retrieve registration record with uid \'%1$s\'', $uid)); return false; } if (!isset($reginfo['email'])) { $this->registerError($this->__f('Error! The registration record with uid \'%1$s\' does not contain an e-mail address.', $uid)); return false; } } if ($this->currentUserIsAdmin() && isset($args['force']) && $args['force']) { $forceVerification = true; } else { $forceVerification = false; } if (isset($args['rendererArgs']) && is_array($args['rendererArgs'])) { $rendererArgs = $args['rendererArgs']; } else { $rendererArgs = array(); } $approvalOrder = $this->getVar('moderation_order', Users_Constant::APPROVAL_BEFORE); // Set the verification code if (isset($reginfo['isverified']) && $reginfo['isverified']) { $this->registerError($this->__f('Error! A verification code cannot be sent for the registration record for \'%1$s\'. It is already verified.', $reginfo['uname'])); return false; } elseif (!$forceVerification && ($approvalOrder == Users_Constant::APPROVAL_BEFORE) && isset($reginfo['approvedby']) && !empty($reginfo['approved_by'])) { $this->registerError($this->__f('Error! A verification code cannot be sent for the registration record for \'%1$s\'. It must first be approved.', $reginfo['uname'])); return false; } $nowUTC = new DateTime(null, new DateTimeZone('UTC')); $verificationCode = UserUtil::generatePassword(); ModUtil::apiFunc($this->name, 'user', 'resetVerifyChgFor', array( 'uid' => $reginfo['uid'], 'changetype'=> Users_Constant::VERIFYCHGTYPE_REGEMAIL, )); $verifyChgObj = array( 'changetype'=> Users_Constant::VERIFYCHGTYPE_REGEMAIL, 'uid' => $reginfo['uid'], 'newemail' => $reginfo['email'], 'verifycode'=> UserUtil::getHashedPassword($verificationCode), 'created_dt'=> $nowUTC->format(Users_Constant::DATETIME_FORMAT), ); $verifyChgObj = DBUtil::insertObject($verifyChgObj, 'users_verifychg'); if (!$verifyChgObj) { $this->registerError($this->__f('Error! Unable to save the verification code for the registration for \'%1$s\'.', $reginfo['uname'])); return false; } if (empty($rendererArgs)) { $siteurl = System::getBaseUrl(); $rendererArgs = array(); $rendererArgs['sitename'] = System::getVar('sitename'); $rendererArgs['siteurl'] = substr($siteurl, 0, strlen($siteurl)-1); } $rendererArgs['reginfo'] = $reginfo; $rendererArgs['verifycode'] = $verificationCode; $rendererArgs['approvalorder'] = $approvalOrder; $codeSent = ModUtil::apiFunc($this->name, 'user', 'sendNotification', array( 'toAddress' => $reginfo['email'], 'notificationType' => 'regverifyemail', 'templateArgs' => $rendererArgs, )); if ($codeSent) { return $verifyChgObj['created_dt']; } else { DBUtil::deleteObject($verifyChgObj, 'users_verifychg'); return false; } }
/** * Save the preliminary user e-mail until user's confirmation. * * Parameters passed in the $args array: * ------------------------------------- * string $args['newemail'] The new e-mail address to store pending confirmation. * * @param array $args All parameters passed to this function. * * @return bool True if success and false otherwise. * * @throws Zikula_Exception_Forbidden Thrown if the current user is logged in. */ public function savePreEmail($args) { if (!UserUtil::isLoggedIn()) { throw new Zikula_Exception_Forbidden(); } $dbinfo = DBUtil::getTables(); $verifychgColumn = $dbinfo['users_verifychg_column']; $nowUTC = new DateTime(null, new DateTimeZone('UTC')); $uid = UserUtil::getVar('uid'); $uname = UserUtil::getVar('uname'); // generate a randomize value of 7 characters needed to confirm the e-mail change $confirmCode = UserUtil::generatePassword(); $confirmCodeHash = UserUtil::getHashedPassword($confirmCode); $obj = array( 'changetype' => Users_Constant::VERIFYCHGTYPE_EMAIL, 'uid' => $uid, 'newemail' => DataUtil::formatForStore($args['newemail']), 'verifycode' => $confirmCodeHash, 'created_dt' => $nowUTC->format(Users_Constant::DATETIME_FORMAT), ); DBUtil::deleteWhere('users_verifychg', "({$verifychgColumn['uid']} = {$uid}) AND ({$verifychgColumn['changetype']} = " . Users_Constant::VERIFYCHGTYPE_EMAIL . ")"); $obj = DBUtil::insertObject($obj, 'users_verifychg', 'id'); if (!$obj) { return false; } // send confirmation e-mail to user with the changing code $subject = $this->__f('Confirmation change of e-mail for %s', $uname); $view = Zikula_View::getInstance($this->name, false); $viewArgs = array( 'uname' => $uname, 'email' => UserUtil::getVar('email'), 'newemail' => $args['newemail'], 'sitename' => System::getVar('sitename'), 'url' => ModUtil::url($this->name, 'user', 'confirmChEmail', array('confirmcode' => $confirmCode), null, null, true), ); $view->assign($viewArgs); $message = $view->fetch('users_email_userverifyemail_html.tpl'); $sent = ModUtil::apiFunc('Mailer', 'user', 'sendMessage', array( 'toaddress' => $args['newemail'], 'subject' => $subject, 'body' => $message, 'html' => true )); if (!$sent) { return false; } return true; }