/** * Votes for something * @param {string} forType the type of thing to vote for * @param {string} forId string uniquely identifying that thing among others of its type * @param {integer} value the value the user has voted for, such as a rating etc. */ function Users_vote_post() { $user = Users::loggedInUser(true); $required = array('forType', 'forId'); foreach ($required as $field) { if (empty($_REQUEST[$field])) { throw new Q_Exception_RequiredField(compact('field')); } } $value = Q_Config::get('Users', 'vote', $_REQUEST['forType'], 'value', null); if (isset($value)) { $_REQUEST['value'] = $value; } else { if (!isset($_REQUEST['value'])) { $_REQUEST['value'] = 1; } } if ($_REQUEST['forType'] === 'Users/hinted') { $hinted = Q::ifset($_SESSION, 'Users', 'hinted', array()); if (!in_array($_REQUEST['forId'], $hinted)) { $_SESSION['Users']['hinted'][] = $_REQUEST['forId']; } } $vote = new Users_Vote(); $vote->userId = $user->id; $vote->forType = $_REQUEST['forType']; $vote->forId = $_REQUEST['forId']; $vote->value = $_REQUEST['value']; $retrieved = $vote->retrieve(); /** * @event Users/vote {before} * @return {string} */ if (false === Q::event('Users/vote', compact('user', 'vote'), 'before')) { return; } if (!$retrieved) { $vote->save(); } $vote = $vote->exportArray(); $vote['retrieved'] = $retrieved; Users::$cache['vote'] = $vote; }
/** * Returns a vote or value, if one is there * @param {string} forType the type of thing to vote for * @param {string} forId string uniquely identifying that thing among others of its type */ function Users_vote_response() { if (isset(Users::$cache['vote'])) { $vote = Users::$cache['vote']; } else { $required = array('forType', 'forId'); foreach ($required as $field) { if (empty($_REQUEST[$field])) { throw new Q_Exception_RequiredField(compact('field')); } } $user = Users::loggedInUser(true); $vote = new Users_Vote(); $vote->userId = $user->id; $vote->forType = $_REQUEST['forType']; $vote->forId = $_REQUEST['forId']; $retrieved = $vote->retrieve(); $vote = $vote->exportArray(); $vote['retrieved'] = $retrieved; } Q_Response::setSlot('vote', $vote ? $vote : false); Q_Response::setSlot('value', $vote ? $vote['value'] : false); }
/** * Use with caution! This bypasses authentication. * This functionality should not be exposed externally. * @method setLoggedInUser * @static * @param {Users_User|string} $user The user object or user id */ static function setLoggedInUser($user = null) { if (!$user) { return Users::logout(); } if (is_string($user)) { $user = Users_User::fetch($user); } if (isset($_SESSION['Users']['loggedInUser']['id'])) { if ($user->id == $_SESSION['Users']['loggedInUser']['id']) { // This user is already the logged-in user. return; } } if ($sessionId = Q_Session::id()) { // Change the session id to prevent session fixation attacks $sessionId = Q_Session::regenerateId(true); } // Store the new information in the session $snf = Q_Config::get('Q', 'session', 'nonceField', 'nonce'); $_SESSION['Users']['loggedInUser']['id'] = $user->id; Q_Session::setNonce(true); $user->sessionCount = isset($user->sessionCount) ? $user->sessionCount + 1 : 1; // Do we need to update it? if (Q_Config::get('Users', 'setLoggedInUser', 'updateSessionKey', true)) { /** * @event Users/setLoggedInUser/updateSessionKey {before} * @param {Users_User} user */ Q::event('Users/setLoggedInUser/updateSessionKey', compact('user'), 'before'); $user->sessionId = $sessionId; $user->save(); // update sessionId in user /** * @event Users/setLoggedInUser/updateSessionKey {after} * @param {Users_User} user */ Q::event('Users/setLoggedInUser/updateSessionKey', compact('user'), 'after'); } $votes = Users_Vote::select('*')->where(array('userId' => $user->id, 'forType' => 'Users/hinted'))->fetchDbRows(null, null, 'forId'); // Cache already shown hints in the session. // The consistency of this mechanism across sessions is not perfect, i.e. // the same hint may repeat in multiple concurrent sessions, but it's ok. $_SESSION['Users']['hinted'] = array_keys($votes); /** * @event Users/setLoggedInUser {after} * @param {Users_User} user */ Q::event('Users/setLoggedInUser', compact('user'), 'after'); self::$loggedOut = false; }
/** * Calculates total votes * @method beforeRemove * @param {array} $pk * @return {boolean} */ function beforeRemove($pk) { $vote = new Users_Vote(); $vote->userId = $this->userId; $vote->forType = $this->forType; $vote->forId = $this->forId; if ($vote->retrieve()) { $total = new Users_Total(); $total->forType = $vote->forType; $total->forId = $vote->forId; if ($total->retrieve('*', false, array('begin' => true))) { $weightTotal = $total->weightTotal; $total->set('transaction', true); $total->weightTotal -= $vote->weight; if (!$total->weightTotal) { $total->value = 0; } else { $total->value = ($total->value * $weightTotal - $vote->value * $vote->weight) / $total->weightTotal; } $total->voteCount -= 1; } else { // something is wrong ... if there are votes, there should have been a total $total->weightTotal = 0; $total->voteCount = 0; $total->value = 0; } $this->set('total', $total); } return true; }