/** * Starts the process of adding an email to a saved user object. * Also modifies and saves this user object back to the database. * @method addEmail * @param {string} $emailAddress * The email address to add. * @param {string} [$activationEmailSubject=null] * The subject of the activation email to send. * @param {string} [$activationEmailView=null] * The view to use for the body of the activation email to send. * @param {boolean} [$html=true] * Defaults to true. Whether to send as HTML email. * @param {array} [$fields=array()] * An array of additional fields to pass to the email view. * @param {array} $options=array() * Array of options. Can include:<br/> * "html" => Defaults to false. Whether to send as HTML email.<br/> * "name" => A human-readable name in addition to the address.<br/> * "from" => An array of (emailAddress, human_readable_name)<br/> * "delay" => A delay, in milliseconds, to wait until sending email. Only works if Node server is listening. * @return {boolean} * Returns true on success. * Returns false if this email address is already verified for this user. * @throws {Q_Exception_WrongValue} * If the email address is in an invalid format, this is thrown. * @throws {Users_Exception_AlreadyVerified} * If the email address already exists and has been verified for * another user, then this exception is thrown. */ function addEmail($emailAddress, $activationEmailSubject = null, $activationEmailView = null, $fields = array(), $options = array()) { if (!isset($options['html'])) { $options['html'] = true; } if (!Q_Valid::email($emailAddress, $normalized)) { throw new Q_Exception_WrongValue(array('field' => 'Email', 'range' => 'a valid address'), 'emailAddress'); } $email = new Users_Email(); $email->address = $normalized; if ($email->retrieve('*', array('ignoreCache' => true)) and $email->state !== 'unverified') { if ($email->userId === $this->id) { $email->set('user', $this); return $email; } // Otherwise, say it's verified for another user, // even if it unsubscribed or was suspended. throw new Users_Exception_AlreadyVerified(array('key' => 'email address', 'userId' => $email->userId), 'emailAddress'); } $user = $this; // If we are here, then the email record either // doesn't exist, or hasn't been verified yet. // In either event, update the record in the database, // and re-send the email. $minutes = Q_Config::get('Users', 'activation', 'expires', 60 * 24 * 7); $email->state = 'unverified'; $email->userId = $this->id; $email->activationCode = strtolower(Q_Utils::unique(7)); $email->activationCodeExpires = new Db_Expression("CURRENT_TIMESTAMP + INTERVAL {$minutes} MINUTE"); $email->authCode = md5(microtime() + mt_rand()); $link = 'Users/activate?code=' . urlencode($email->activationCode) . ' emailAddress=' . urlencode($email->address); /** * @event Users/addIdentifier {before} * @param {string} user * @param {string} email */ Q::event('Users/addIdentifier', compact('user', 'email', 'link'), 'before'); $email->save(); $this->emailAddressPending = $normalized; $this->save(); if (!isset($activationEmailView)) { $activationEmailView = Q_Config::get('Users', 'transactional', 'activation', 'body', 'Users/email/activation.php'); } if (!isset($activationEmailSubject)) { $activationEmailSubject = Q_Config::get('Users', 'transactional', 'activation', 'subject', "Welcome! Please confirm your email address."); } $fields2 = array_merge($fields, array('user' => $this, 'email' => $email, 'app' => Q_Config::expect('Q', 'app'), 'baseUrl' => Q_Request::baseUrl(), 'link' => $link)); $email->sendMessage($activationEmailSubject, $activationEmailView, $fields2, $options); // may throw exception if badly configured /** * @event Users/addIdentifier {after} * @param {string} user * @param {string} email */ Q::event('Users/addIdentifier', compact('user', 'email', 'link'), 'after'); }