/** * Returns a user in the database that will correspond to a new user in the future * once they authenticate or follow an invite. * Inserts a new user if one doesn't already exist. * * @method futureUser * @param {string} $type Could be one of "email", "mobile", "email_hashed", "mobile_hashed", "facebook", "twitter" or "none". * @param {string} $value The value corresponding to the type. If $type is: * * * "email" - this is one of the user's email addresses * * "mobile" - this is one of the user's mobile numbers * * "email_hashed" - this is the email, already hashed with Q_Utils::hash() * * "mobile_hashed" - this is the email, already hashed with Q_Utils::hash() * * "facebook" - this is the user's id on facebook * * "twitter" - this is the user's id on twitter * * "none" - the type is ignored, no "identify" rows are inserted into the db, etc. * * With every type except "none", the user will be * * NOTE: If the person we are representing here comes and registers the regular way, * and then later adds an email, mobile, or authenticates with a provider, * which happens to match the "future" mapping we inserted in users_identify table, * then this futureUser will not be converted, since they already registered * a different user. Later on, we may have some sort function to merge users together. * * @param {&string} [$status=null] The status of the user - 'verified' or 'future' * @return {Users_User} * @throws {Q_Exception_WrongType} If $type is not supported * @throws {Q_Exception_MissingRow} If identity for user exists but user does not exists */ static function futureUser($type, $value, &$status = null) { if (!array_key_exists($type, self::$types)) { throw new Q_Exception_WrongType(array('field' => 'type', 'type' => 'one of the supported types')); } if ($type !== 'none') { $ui = Users::identify($type, $value, null); if ($ui && !empty($ui->userId)) { $user = new Users_User(); $user->id = $ui->userId; if ($user->retrieve()) { $status = $ui->state; return $user; } else { $userId = $ui->userId; throw new Q_Exception_MissingRow(array('table' => 'user', 'criteria' => 'that id'), 'userId'); } } } // Make a user row to represent a "future" user and give them an empty username $user = new Users_User(); if ($field = self::$types[$type]) { $user->{$field} = $value; } $user->signedUpWith = 'none'; // this marks it as a future user for now $user->username = ""; $user->icon = 'future'; $during = 'future'; /** * @event Users/insertUser {before} * @param {string} during * @param {Users_User} 'user' */ Q::event('Users/insertUser', compact('user', 'during'), 'before'); $user->save(); // sets the user's id /** * @event Users/insertUser {after} * @param {string} during * @param {Users_User} user */ Q::event('Users/insertUser', compact('user', 'during'), 'after'); if ($type != 'email' and $type != 'mobile') { if ($type !== 'none') { // Save an identifier => user pair for this future user $ui = new Users_Identify(); $ui->identifier = "{$type}:{$value}"; $ui->state = 'future'; if (!$ui->retrieve()) { $ui->userId = $user->id; $ui->save(); } $status = $ui->state; } else { $status = 'future'; } } else { // Save hashed version $ui = new Users_Identify(); $hashed = Q_Utils::hash($value); $ui->identifier = $type . "_hashed:{$hashed}"; $ui->state = 'future'; if (!$ui->retrieve()) { $ui->userId = $user->id; $ui->save(); } $status = $ui->state; } return $user; }