Posted by mercmobily on June 5, 2009 at 8:29am
8 followers
Jump to:
| Project: | Voting API |
| Version: | 5.x-1.6 |
| Component: | Code |
| Category: | support request |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | closed (won't fix) |
Issue Summary
Hi,
I am the author of Extra Voting Forms and would like to implement anonymous voting "the right way" using VotingAPI.
At the moment, when a user votes, I just do:
// Give the actual vote using the Voting API
$votes = array();
$votes['content_type'] = extra_voting_forms_c($o->sk_type);
$votes['content_id'] = $o->sk_id;
$votes['uid'] = $account->uid;
$votes['value_type'] = 'points';
$votes['value'] = $vote;
$result = votingapi_set_votes($votes);And then I load the total for that node:
// Get the current number of votes
$criteria = array();
$criteria['content_type'] = extra_voting_forms_c($o->sk_type);
$criteria['content_id'] = $o->sk_id;
$criteria['tag'] = 'vote';
$criteria['value_type'] = 'points';
$criteria['function'] = 'sum';
$r = votingapi_select_results($criteria);
$r = (int)$r[0]['value'];When I show the form, I go:
// ****************************************************************
// ** SET THE BASIC VARIABLES
// ****************************************************************
// This will get the record. If != NULL, then a vote (even 0) WAS cast
$criteria = array();
$criteria['content_type'] = extra_voting_forms_c($o->sk_type);
$criteria['content_id'] = $o->sk_id;
$criteria['value_type'] = 'points';
$criteria['tag'] = 'vote';
$criteria['uid'] = $user->uid;
$existing_vote_cast = votingapi_select_votes($criteria);Now... I am trying to work out what the "right" way to add anonymous voting so that it's the "VotingAPI" way.
I am a little confused by the code in fivestar, which I tried to emulate... unsuccessfully.
So, what are the "basic requirement" to get anonymous vote happening?
I expected to just allow votes from "0", and hoped that VotingAPI would do all the hard stuff to figure out if a vote from from anonymous... but that didn't quite work :D
Please help!
Merc.
Comments
#1
Looking at Votingapi code only, not testing
<?php
// Give the actual vote using the Voting API
$votes = array();
$votes['content_type'] = extra_voting_forms_c($o->sk_type);
$votes['content_id'] = $o->sk_id;
$votes['uid'] = $account->uid;
$votes['value_type'] = 'points';
$votes['value'] = $vote;
if ($account->uid == 0) {
// delete votes where ip_address() is the same and the user is 0
$result = votingapi_set_votes($votes, array('vote_source' => ip_address(), 'uid' => 0));
}
else {
$result = votingapi_set_votes($votes);
}
?>
edit: on your local machine, where vote_source is always the same, it won't appear to work.
To test I would temporary modify ip_address() function to return random stuff or deploy to a testing server. There is a anon testing window that will save ya there and its default value is an hour. On the flip side, if you don't want to delete the anon vote cast by the same ip, pass in an empty array instead (also note, empty array() is decidedly different then NULL and VotingAPI does different behavior).#2
Hi,
Thank you for your help!
OK, I am following you up to this point:
> There is a anon testing window that will save ya there and its default value is an hour.
OK... so votes from the same IP address within 1 hour will be considered as coming from the same anon user?
> On the flip side, if you don't want to delete the anon vote cast by the same ip, pass in an empty array instead
> (also note, empty array() is decidedly different then NULL and VotingAPI does different behavior).
This is where I lost you totally :D Sorry...! What do you mean?
Merc.
#3
Hi,
And... what about the "loading" side of the story? When I load the existing vote (which will influence what the voting form displays), do I have to take special precautions? (See: load filtering by ip_address() for example...?)
Merc
#4
subscribing!!
#5
subs
#6
hi,
I got your problem about enable anonimous users to vote,
i just developed a simply (relatively simple) solution trough some hack code for 'Extra Voting forms' and 'Voting API' modules.
I hope that this solution is useful to you and all those who needed it, I did some tests and it seems that everything works.
Not much to modify a few lines of code to replace, becouse your modules are written very well, clean code and fairly commented.
So in few hours, i was able to study it and try to develop a solution.
Now I will try to explain the various changes. Let's go...
Roughly, the procedure is to check if the node has been already commented or not, even when the user is anonymous with the unique foresight to also filter by hostname.
my comment is long and seems to have upset the module code. But is not true! I only "let pass" anonymous users in some functions, and check the hostname before voting again to an anonymous user. in fact the two modules were already predisposed for vote anonimous users.
I use the version 5.x.1.6 for both modules.
frist step: open extra_voting_forms.module
go to the function extra_voting_forms_handle() and
replace:
<?phpif ($form_type != 'ajax' && $user->uid == 0 ) {
drupal_goto(extra_voting_forms_anonymous_url(), "destination=". extra_voting_forms_destination($o) );
}
?>
with
<?phpif ($form_type != 'ajax') {
drupal_goto(extra_voting_forms_anonymous_url(), "destination=". extra_voting_forms_destination($o) );
}
?>
now also anonimous can redirect to the function extra_voting_forms_give_vote so got to this function and
replace
<?phpif ($account->uid == 0) {
return array( t("Only logged in users can vote!"), 0 );
}
?>
with
<?phpif ($account->uid == 0) {
// you can see this code at the end of the function, first runned only by authenticated users, now also by anonymous users
$v = new stdClass();
$v->value = $vote;
$v->value_type = 'points';
$v->tag = 'vote';
votingapi_set_vote(extra_voting_forms_c($o->sk_type), $o->sk_id, $v, $account->uid);
$r = votingapi_get_voting_result(extra_voting_forms_c($o->sk_type), $o->sk_id, 'points', 'vote', 'sum');
$r = (int)$r->value;
return array('', $r);
}
?>
ok, now go to the function extra_voting_forms_show_form
<?php$action = base_path() ."extra_voting_forms/handle";
// Voting is "sort of" allowed to anonymous...!
// The voter will be redirected...
$draw_js_destination_variable = FALSE;
if ($user->uid == 0) {
//COMMENT HERE $voting_not_allowed = FALSE;
//COMMENT HERE $draw_js_destination_variable = TRUE;
}
?>
simply comment the two lines as above, in fact the anonimous user already enabled to see the correct voting form
now, few lines above... replace this code
<?php// This will get the record. If != NULL, then a vote (even 0) WAS cast
$existing_vote_cast = votingapi_get_vote(extra_voting_forms_c($o->sk_type), $o->sk_id, 'points', 'vote', $user->uid);
?>
with
<?phpif ($user->uid == '0'){
$mioHostname = $_SERVER['REMOTE_ADDR'];
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) $mioHostname .= '-'. $_SERVER['HTTP_X_FORWARDED_FOR'];
// this code is like the function 'votingapi_get_vote', but also filters the hostname
$result = db_query("SELECT * FROM {votingapi_vote} v WHERE content_type='%s'
AND content_id=%d AND value_type='%s' AND tag='%s' AND uid=%d
AND hostname='{$mioHostname}'",
extra_voting_forms_c($o->sk_type), $o->sk_id, 'points', 'vote', $user->uid);
$existing_vote_cast = db_fetch_object($result);
}
else $existing_vote_cast = votingapi_get_vote(extra_voting_forms_c($o->sk_type), $o->sk_id, 'points', 'vote', $user->uid);
?>
This may seem like a substantial change but in fact it is not. I just added a condition to the query in the function 'votingapi_get_vote'.
There is some redundancy in the code, I know, but this hack and it is certainly improvable, i prefered don't change many functions to understand the dynamics of the hack.
Now just last (little) change in the file votingapi.module
go to the function votingapi_set_vote that is the core of all :) and enable anonymous users to add the vote. Discriminating hostname. Far we have dealt the 'voting form'
replace
<?phpwhile ($vobj = db_fetch_object($result)) {
votingapi_change_vote($vobj, $vote->value);
$exists = TRUE;
}
?>
with
<?php$mioHostname = $_SERVER['REMOTE_ADDR'];
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) $mioHostname .= '-'. $_SERVER['HTTP_X_FORWARDED_FOR'];
while ($vobj = db_fetch_object($result)) {
if ( $vobj->uid == '0') {
if ($vobj->hostname == $mioHostname){
votingapi_change_vote($vobj, $vote->value);
$exists = TRUE;
}
}
else {
votingapi_change_vote($vobj, $vote->value);
$exists = TRUE;
}
}
?>
it seem all, and seem it work... but i will monitor this post to see if there will be problems.
#7
jamme, I tried your suggestions, but unfortunately they do not work for 6.x version of the modules. The changes in EVF were fine, but the code of Voting Api is somewhat changed and I can't apply your changes there. The function votingapi_set_vote is no longer there, now they have votingapi_set_votes, which is different.
#8
I recently made a patch for EVF that enables anonymous voting. See it here:
http://drupal.org/node/335617#comment-2366704
#9
Greetings. To Whom it may concern ; I applied the jamme's code, I am using Drupal version 5.23 and 5.16 of the EVF.
But when one guest votes an other guest can't vote the same comment
Is there a patch file for Drupal 5 ? Or How can I solve this problem ? thank your very much , very truly yours ,
Sonsuz Us
#10
Support for the 5.x branch of VotingAPI has ended with the release of Drupal 7 and the upcoming release of VotingAPI 7.x-2.4.