function _advpoll_calculate_bordacount in Advanced Poll 6
Same name and namespace in other branches
- 5 modes/ranking.inc \_advpoll_calculate_bordacount()
- 6.3 modes/ranking.inc \_advpoll_calculate_bordacount()
- 6.2 modes/ranking.inc \_advpoll_calculate_bordacount()
Calculate the results using borda count.
Parameters
$node: The node object for the current poll.
Return value
Should return an object that include the following attributes -results : 2d array listing the aggregate preference, including ties -rounds : 2d array listing the per-choice vote count for each round and a status message indicating who was eliminated -totalVoters : the total number of voters who participated
1 call to _advpoll_calculate_bordacount()
- advpoll_calculate_results_ranking in modes/
ranking.inc - Calculate the results for a ranking poll based on the algorithm.
File
- modes/
ranking.inc, line 400 - Handle ranking votes, e.g. choice A is preferred over choice B, which in turn is preferred over choice C.
Code
function _advpoll_calculate_bordacount($node) {
$votes = array();
// ORDER BY value ASC lets us ensure no gaps.
$result = db_query("SELECT * FROM {votingapi_vote} v WHERE content_type = '%s' AND content_id = %d ORDER BY value ASC", 'advpoll', $node->nid);
while ($vobj = db_fetch_object($result)) {
$votes[] = $vobj;
}
if (count($votes) == 0) {
// No votes yet.
return array();
}
// Aggregate votes by user (uid if logged in, IP if anonymous)
// in ascending order of value.
$user_votes = array();
foreach ($votes as $vote) {
if ($vote->uid == 0) {
// Anonymous user.
$key = $vote->vote_source;
}
else {
// Logged-in user.
$key = $vote->uid;
}
$user_votes[$key][$vote->value] = $vote->tag;
}
$choice_votes = array();
$total_choices = count($node->choice);
$total_points = 0;
// Loop through each user's vote
foreach ($user_votes as $uid => $user_vote) {
foreach ($user_vote as $ranking => $choice) {
// Negative values are possible if choices were removed after vote
$vote_value = max($total_choices - $ranking, 0);
isset($choice_votes[$choice]) ? $choice_votes[$choice] += $vote_value : ($choice_votes[$choice] = $vote_value);
$total_points += $vote_value;
}
}
// Add any remaining choices that received no votes.
foreach ($node->choice as $i => $choice) {
if (!isset($choice_votes[$i])) {
// Didn't receive any votes
$choice_votes[$i] = 0;
}
}
// Sort descending (although there may be ties).
arsort($choice_votes);
// Figure out the final ranking.
$ranking = array();
$previous_total = -1;
$cur_result = -1;
foreach ($choice_votes as $choice => $total) {
if ($total != $previous_total) {
// Didn't tie with the previous score.
$cur_result++;
}
$ranking[$cur_result]['choices'][] = $choice;
$ranking[$cur_result]['raw_score'] = $total;
$ranking[$cur_result]['view_score'] = format_plural($total, '1 point', '@count points');
$ranking[$cur_result]['percentage'] = $total_points ? $total / $total_points : 0;
$previous_total = $total;
}
$total_votes = count($user_votes);
$result_obj->ranking = $ranking;
$result_obj->total_votes = $total_votes;
$result_obj->total_points = $total_points;
return $result_obj;
}