separated number of votes instead of total sum
c-c-m - March 25, 2009 - 22:29
| Project: | Vote Up/Down |
| Version: | 6.x-1.0-beta6 |
| Component: | User interface |
| Category: | feature request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | active |
Description
Could it be possible to display the number of positive votes as well as the negative ones instead of displaying the total sum of votes? If not, it would be interesting to know the number of votes a node has received.
Thanks

#1
I am actually trying to achieve the same thing. ( thumbs up, thumbs down kind of thing)
I think that one way to do it would be to rate negative votes as "0 point" whereas positive votes are equal to "1 point".
Then, the negative votes count could be the difference between total votes count and sum of points.
Your positive votes count will be the sum of points.
To do this, I had a look at votingapi in order to hook before inserting the vote in database and modify the value of negative vote from "-1" to "0".
The only thing is that the hook_insert happens after the insert in database.
One other way to do it would be to alter vote up/down module so that you can choose the points value for each positive or negative vote.
Anyway, i am still testing, will let you know if i have any success.
:)
#2
Hey lafouch
for what it's worth, i've kind of dabbled with that module and voting_api to write a small module to promote nodes to front page based on voting results of the vote_up_down module and i have used the following hook to do so, on line 397 of the votingapi.module :
// Give other modules a chance to act on the results of the vote totaling.
module_invoke_all('votingapi_results', $cached, $content_type, $content_id);
and found out the following to use in my module :
$cached[0]['value'] returns the total number of votes
$cached[1]['value'] returns the average result, bet 0 & 1 (or if you want , in percentage, the sum of + & - votes div by total votes)
$cached[2]['value'] returns the sum of + and - votes
hope that helps
#3
Hi lafouch,
I have had success with the following theme override. Just paste it into the template.php file in your theme's folder.
poloparis shows you can get three different results from the results array, but actually, the key was to switch the votingapi function to select_votes rather than select_result_value. I then used php to tally up the votes for either 1 or -1 values. Anyway, the code below should be close to what you're looking for.
function phptemplate_vote_up_down_points($cid, $type, $tag = NULL, $nodelink = FALSE) {
$tag = $tag ? $tag : variable_get('vote_up_down_tag', 'vote');
$criteria = array('content_type' => $type, 'content_id' => $cid, 'value_type' => 'points', 'tag' => $tag //, 'function' => 'sum'
);
$votes = votingapi_select_votes($criteria);
$items = array(); $results_upvote = $results_downvote = 0;
foreach ($votes as $vote) {
if ($vote['value']>0) $results_upvote += $vote['value'];
elseif ($vote['value']<0) $results_downvote += $vote['value'];
}
$items[] = array('class'=>'upvote','data'=>'<strong>'. $results_upvote .'</strong> <span>up</span>');
$items[] = array('class'=>'downvote','data'=>'<strong>'. $results_downvote .'</strong> <span>down</span>');
if ($nodelink) {
foreach($items as $item) $title .= '<span class="'.$item['class'].'">'.$item['data'].'</span>';
$output = array(
'title' => $title,
'html' => TRUE
);
}
else {
$output = theme('item_list',$items,null,'ul',array('id'=>'vote_points_'. $cid,'class'=>'vote-points'));
}
return $output;
}
#4
Thanks to both of you,
i finally used the hook_votingapi_results_alter in the following way to get :
- negative votes, positive votes and percentage of positive votes among all votes
function thumbs_votingapi_results_alter(&$cache, $content_type, $content_id){
$sql = "SELECT count(*) as positive_count ";
$sql .= "FROM {votingapi_vote} v ";
$sql .= "WHERE v.content_type = '%s' AND v.content_id = %d ";
$sql .= "AND v.value_type = 'points' AND v.value = 1";
$results = db_query($sql, $content_type, $content_id);
while ($result = db_fetch_array($results)) {
$cache['thumb']['points']['positive'] = $result['positive_count'];
}
$cache['thumb']['points']['negative']=$cache['vote']['points']['sum']-$cache['thumb']['points']['positive'];
$cache['thumb']['percent']['average_success']=($cache['thumb']['points']['positive']/$cache['vote']['points']['sum'])*100;
}
then the values are available with the votingapi_select_results($criteria);
#5
Can somebody help me with one function.
I want to implement hook_voingapi_results_alter() in vote up down module.
I have this code for votingapi version 1.x , I'm trying to change it to version 2.x .
I don't know how to check the current vote value : if ($vote->value == -1) -this doesn't work in votingapi 2.x
please help.
/*** Implementation of hook_votingapi_calculate().
*
* @param $cache
* an array of {votingapi_cache} records. Here you put your stuff in there. It is keyed by $tag, $type, $function
*
*/
function vote_up_down_votingapi_calculate(&$cache, $votes, $content_type, $content_id) {
foreach ($votes as $vote) {
if ($vote->value == -1) {
$cache[$vote->tag][$vote->content_type]['thumbs_down']++;
}
else if ($vote->value == 1) {
$cache[$vote->tag][$vote->content_type]['thumbs_up']++;
}
}
}
In version 2.x it doesn't get the $vote->value .
This hook_votingapi_calculate(&$cache, $votes, $content_type, $content_id) has changed to hook_votingapi_results_alter(&$cache, $content_type, $content_id) .
What happen with the $votes array ? How can I get the current vote value ?
#6
did you get this to work?
#7
yes but not with this hook. I had some problems with the implementation so I modified the voting api module.
I added this 3 lines to votingapi:
function _votingapi_get_standard_results($content_type, $content_id)...
$votesdown = ( $result['value_count'] - $result['value_sum'] ) / 2 ;
$cache[$result['tag']][$result['value_type']]['votes_down'] = $votesdown;
$cache[$result['tag']][$result['value_type']]['votes_up'] = $result['value_count'] - $votesdown ;
...
and it works fine for me. However, it's not a good idea to do it this way. It should be done with this hook:
hook_voingapi_results_alter() in vote up down module !!!!!!!!!!!!!!!!!
Now it calculates the values everytime somebody votes.
To see the result you have to add this to the theme function of vote up down module:
function template_preprocess_vote_up_down_points(&$variables) {
...
$criteria1 = array(
'content_type' => $variables['type'],
'content_id' => $variables['cid'],
'value_type' => 'points',
'tag' => $tag,
'function' => 'votes_down'
);
$criteria2 = array(
'content_type' => $variables['type'],
'content_id' => $variables['cid'],
'value_type' => 'points',
'tag' => $tag,
'function' => 'votes_up'
);
$vote_result_downs = (int)votingapi_select_single_result_value($criteria1);
$vote_result_ups = (int)votingapi_select_single_result_value($criteria2);
$variables['points_down_labelled'] = format_plural($vote_result_downs, '1 down ', '@count down ');
$variables['points_up_labelled'] = format_plural($vote_result_ups, '1 up, ', '@count up, ');
...
and you have to edit this file: vote_up_down_points.tpl.php
The up point are stored now in $points_up_labelled.
For example you can add this 2 lines to the tpl file:
<span id="vote_points_<?php print $cid; ?>" class="vote-points"><span class="<?php print $class; ?>"><?php print $points_up_labelled; ?></span></span><span id="vote_points_<?php print $cid; ?>" class="vote-points"><span class="<?php print $class; ?>"><?php print $points_down_labelled; ?></span></span>
You also may want to edit the css file.
#8
if you have the voting counts and sum, you can calculate the ups and downs :
downpoints = (count - sum) /2
uppoints = count - downpoints
#9
subscribing
#10
Tried to get this to work but I'm not a programmer and good with code so I'm sure I screwed it up. Do you only add the code or do you need to modify the existing code? Maybe you could dumb it down for me so I can get this working. Thanks.
#11
subscribing
#12
Plus vote = Number of Plus votes
Minus vote = Number of Minus votes
count = Plus vote + Minus vote
sum = Plus vote - Minus vote
Solving these equations give the following results for Plus and Minus votes-
Plus vote = (count + sum)/2
Minus vote = (count - sum)/2
Now these can be used in the vote up down module to get the desired results. I think it does not require to alter votingapi module.
#13
subscribing
#14
I got this to work with one small problem. When I view a node that his this voting enabled, the results say 0 up 0 down. Then when I vote "up" I see 1 up 0 down 0 down. The extra "0 down" is the problem. If I switch the order of the results it does the same thing. Obviously the second result that is being shown is not getting cleared. When I print only the up results or only the down results everything works fine. So there must be some place in the code where you have to tell it to clear both values instead of just one.
Dave
#15
Here is where I put the code in the votingapi.module file:
function _votingapi_get_standard_results($content_type, $content_id) {
$cache = array();
$sql = "SELECT v.value_type, v.tag, ";
$sql .= "COUNT(v.value) as value_count, SUM(v.value) as value_sum ";
$sql .= "FROM {votingapi_vote} v ";
$sql .= "WHERE v.content_type = '%s' AND v.content_id = %d AND v.value_type IN ('points', 'percent') ";
$sql .= "GROUP BY v.value_type, v.tag";
$results = db_query($sql, $content_type, $content_id);
while ($result = db_fetch_array($results)) {
$cache[$result['tag']][$result['value_type']]['count'] = $result['value_count'];
$cache[$result['tag']][$result['value_type']]['average'] = $result['value_sum'] / $result['value_count'];
//INSERT CODE HERE
$votesdown = ( $result['value_count'] - $result['value_sum'] ) / 2 ;
$cache[$result['tag']][$result['value_type']]['votes_down'] = $votesdown;
$cache[$result['tag']][$result['value_type']]['votes_up'] = $result['value_count'] - $votesdown ;
//END OF INSERTED CODE
if ($result['value_type'] == 'points') {
$cache[$result['tag']][$result['value_type']]['sum'] = $result['value_sum'];
}
}
Here is where I put the code in vote_up_down.module:
function template_preprocess_vote_up_down_points(&$variables) {
$tag = isset($variables['tag']) ? $variables['tag'] : variable_get('vote_up_down_tag', 'vote');
//INSERT CODE HERE
$criteria1 = array(
'content_type' => $variables['type'],
'content_id' => $variables['cid'],
'value_type' => 'points',
'tag' => $tag,
'function' => 'votes_down'
);
$criteria2 = array(
'content_type' => $variables['type'],
'content_id' => $variables['cid'],
'value_type' => 'points',
'tag' => $tag,
'function' => 'votes_up'
);
$vote_result_downs = (int)votingapi_select_single_result_value($criteria1);
$vote_result_ups = (int)votingapi_select_single_result_value($criteria2);
$variables['points_down_labelled'] = format_plural($vote_result_downs, '1 down ', '@count down ');
$variables['points_up_labelled'] = format_plural($vote_result_ups, '1 up, ', '@count up, ');
//END OF CODE INSERT
Then just modify vote_up_down_points.tpl.php the way tommy said so. Just a little clarification for those who don't know exactly where to put this code.
#16
I am still having trouble with the results not being cleared after a new vote is cast.
I've attached two images that show what is going on.
The first image shows a node for Derek Jeter where one person has voted "up". As you can see it is working correctly - showing 1 up vote, and 0 down votes.
The second image shows what happens after I change this vote to "down". As you can see here, there is an extra "0 down" appended to the end of the results.
It should also be noted that the same thing occurs if I click the "up arrow" after I have already cast a vote. The results aren't effected (so its not like I am voting again), it just displays the "0 down" to the right a second time.
#17
I think some of the ajax code needs to be changed to get rid of this problem.
#18
o yea, changing this to beta6
#19
Is there any way of doing, without hacking the core mod. i am not a programmer so plz be easy on the step of doing it.
#20
Okay, fixed my problem detailed in #16.
Changes need to be made to the code in the vote_up_down.module file and the vote_up_down_points.tpl.php.
Here is the correct code for the vote_up_down.module file:
/**
* Preprocess function for the points in the normal display style.
*/
function template_preprocess_vote_up_down_points(&$variables) {
$tag = isset($variables['tag']) ? $variables['tag'] : variable_get('vote_up_down_tag', 'vote');
$criteria1 = array(
'content_type' => $variables['type'],
'content_id' => $variables['cid'],
'value_type' => 'points',
'tag' => $tag,
'function' => 'votes_down'
);
$criteria2 = array(
'content_type' => $variables['type'],
'content_id' => $variables['cid'],
'value_type' => 'points',
'tag' => $tag,
'function' => 'votes_up'
);
$vote_result_downs = (int)votingapi_select_single_result_value($criteria1);
$vote_result_ups = (int)votingapi_select_single_result_value($criteria2);
//Here is the change from the code I used in comment #15 (see above)
$variables['points_labelled'] = format_plural($vote_result_downs, '1 down ', '@count down ') . format_plural($vote_result_ups, '1 up ', '@count up ');
With this change to the variables['points_labelled'], the tpl file must be changed to this:
<span id="vote_points_<?php print $cid; ?>" class="vote-points"><span class="<?php print $class; ?>"><?php print $points_labelled; ?></span></span>But like khan said, a solution needs to be outlined where hacking the module is not needed. Don't know much about overriding functions, but if someone does help is appreciated. Until then I'm just gonna go with this hack.
#21
I would like to know, how can i write a module to promote the nodes on the front page based on number of votes.
Thanks for your any help.
#22
I'd really like to get this to work, but have tried a few times and not getting it. Or maybe I am getting it, but I don't know how to print the result?
I have tried to follow the directions above - largely #7, #15, and #20 as follows:
1. Modify votingapi.module with code inserted as shown here:
function _votingapi_get_standard_results($content_type, $content_id) {
$cache = array();
$sql = "SELECT v.value_type, v.tag, ";
$sql .= "COUNT(v.value) as value_count, SUM(v.value) as value_sum ";
$sql .= "FROM {votingapi_vote} v ";
$sql .= "WHERE v.content_type = '%s' AND v.content_id = %d AND v.value_type IN ('points', 'percent') ";
$sql .= "GROUP BY v.value_type, v.tag";
$results = db_query($sql, $content_type, $content_id);
while ($result = db_fetch_array($results)) {
$cache[$result['tag']][$result['value_type']]['count'] = $result['value_count'];
$cache[$result['tag']][$result['value_type']]['average'] = $result['value_sum'] / $result['value_count'];
//INSERT CODE HERE
$votesdown = ( $result['value_count'] - $result['value_sum'] ) / 2 ;
$cache[$result['tag']][$result['value_type']]['votes_down'] = $votesdown;
$cache[$result['tag']][$result['value_type']]['votes_up'] = $result['value_count'] - $votesdown ;
//END OF INSERTED CODE
if ($result['value_type'] == 'points') {
$cache[$result['tag']][$result['value_type']]['sum'] = $result['value_sum'];
}
}
2. Modify vote_up_down.module as shown here:
/**
* Preprocess function for the points in the normal display style.
*/
function template_preprocess_vote_up_down_points(&$variables) {
$tag = isset($variables['tag']) ? $variables['tag'] : variable_get('vote_up_down_tag', 'vote');
// begin inserted code
$criteria1 = array(
'content_type' => $variables['type'],
'content_id' => $variables['cid'],
'value_type' => 'points',
'tag' => $tag,
'function' => 'votes_down'
);
$criteria2 = array(
'content_type' => $variables['type'],
'content_id' => $variables['cid'],
'value_type' => 'points',
'tag' => $tag,
'function' => 'votes_up'
);
$vote_result_downs = (int)votingapi_select_single_result_value($criteria1);
$vote_result_ups = (int)votingapi_select_single_result_value($criteria2);
$variables['points_labelled'] = format_plural($vote_result_downs, '1 down ', '@count down ') . format_plural($vote_result_ups, '1 up ', '@count up ');
//end inserted code
$criteria = array(
'content_type' => $variables['type'],
'content_id' => $variables['cid'],
'value_type' => 'points',
'tag' => $tag,
'function' => 'sum'
);
3. Modify vote_up_down_points.tpl.php as shown here:
<span id="vote_points_<?php print $cid; ?>" class="vote-points"><span class="<?php print $class; ?>"><?php print $points_labelled; ?></span></span>// begin inserted code
<span id="vote_points_<?php print $cid; ?>" class="vote-points"><span class="<?php print $class; ?>"><?php print $points_up_labelled; ?></span></span>
<span id="vote_points_<?php print $cid; ?>" class="vote-points"><span class="<?php print $class; ?>"><?php print $points_down_labelled; ?></span></span>
//end inserted code
davedg629 or others, can you confirm this code is correct? I've put it all in place - but not getting a result. Not getting any errors, either, so if it is working, I guess next question is how do I get at the data? What variables do I use to print them to my pages?
I am using on a page with CCK variables. From Contemplate, I got this for printing the widget:
<?php print $node->content['vote_up_down']['#value'];?>This works fine - votes are being recorded, but there are no variables shown in Contemplate to display the up / down results - perhaps that is because the above bits aren't working or perhaps because they are to be found elsewhere. I tried various things, but nothing worked - which isn't surprisingly cause I haven't got a clue what I'm doing.
Can someone offer advice how to get this working?
Thank you!