Because Voting API calls hook_votingapi_insert after updating the database, it's impossible for other modules to know whether a user has voted on the content before.
I'm maintaining Voting Rules integration and users would like to a condition that says 'User votes on content for the first time.' Without this condition, users can score unlimited points, etc, by voting again on the same piece of content.
See http://drupal.org/node/981794
Possible solutions would be to add a pre-insert hook or simply move the insert hook before the database update.
Comments
Comment #1
Taxoman commentedSubscribing (coming from #981794: condition for "user has already voted on node", comment 5)
Comment #2
jessepinho commentedSubscribing as well. Would love to have this feature.
EDIT: Oops; didn't notice the Follow feature. Sweet!
Comment #3
aminalid commentedI would like to have this feature as well.
Comment #4
Taxoman commentedComment #5
BeaPower commentedsub, even to hide the rating fields so that user can leave an ordinary comment if voted
Comment #6
Steven Brown commentedSo correct me if I'm wrong but, we want to move the module_invoke_all() above the function call in our foreach loop. This will allow us to look at $votes to see if any of the users have already voted or is this their first time before the $votes are written to the database.
Comment #7
davidcsonka commentedSubscribing -
This is a critical mechanism for preventing the most basic of exploitations of a voting/points system - "stuffing the ballot box".
Comment #8
BeaPower commentedSame here, what is the update on this?
Comment #9
Steven Brown commentedI will need to go over my notes again, but the short and sweet is, this is the wrong function to be creating this hook. There's another function that is fired off before this that we would need to put the hook in.
I'll do my best to actually explain sometime this weekend.
Comment #10
blackclover commentedsubscribe
Comment #11
m1n0 commentedWhat is the status on this? I am using d6 version but I have the same problem.
Comment #12
m1n0 commentedI made myself patch for this but for 6x-2.3 version but I guess the same will apply for 7.x
It creates one more hook called 'hook_votingapi_pre_insert' before old votes are deleted and new inserted. This way I was easily able to query database to see whether the vote is new or not. (by implementing this hook in my custom module)
Please review and consider commiting into current version.
Comment #13
mermemladeK commentedBump! I am looking for this exact in thing in D7.
Comment #14
torotil commentedThis will be fixed once #1796384: Factor out rate limiting is implemented and perhaps not in 7.x-2.x but in the upcoming 7.x-3.x.
Comment #15
istryker commentedI want to cross-reference this issue with another issue I created. #1880462: Keep track of the previous vote in the database. These are not duplications, just different solutions to the problem.
Comment #16
istryker commentedI notice one problem with this issue, and I might rename it's title.
What happens when you try to cast a vote
Patch #12 adds a hook after the previous vote(s) are deleted and before it added to the database. This can be problematic if you decide in your hook, you want to not add/cast the vote.
I think we need to call
+ module_invoke_all('votingapi_pre_set', $votes);before we find and delete the vote(s).
Comment #17
istryker commentedAttached is my patch
@torotil - I don't think we need to wait for 7.x-3.x. This patch does not break anything. I plan on creating a Voting Rules event that will fix many feature request, such as #1880550: Need: Pre vote or Pre cast Event. Using rules you may be able to solve most of the issues in #1796384: Factor out rate limiting
Comment #18
istryker commentedSo the previous patch does not allow pass by reference. If a module want to unset a vote, they cannot. Switch
module_invoke_all()todrupal_alter()Comment #19
raphael apard commentedi'm using this patch. presave hook can be usefull.
Comment #20
raphael apard commentedHere the patch for D7 version.My bad, patch #18 works fine.
Use hook_votingapi_preset_votes_alter()
Comment #21
raphael apard commentedComment #22
istryker commented@Raphael_Apard why you change the patch, or was this a mistake? I see you changed the argument into an array. This is fine if you are passing in extra arguments from drupal_alter. IE need to know the form id.
array('form', 'form_FORM_ID'). We do not need this. Unless you find a use case, it should be strip for performance. Patch #18 should be used.Changing status to RTBC as @Raphael_Apard has tested this.
Comment #23
raphael apard commented@iStryker, yes it was a mistake. Patch #18 works fine.
Comment #24
torotil commentedWe'd also need to document this new hook_votingapi_preset_vote_alter() in votingapi.api.php. I promise to commit this as soon as there is a patch that includes useful documentation.
Comment #25
mxtOther issues/feature requests depends on this important feature, for example:
http://drupal.org/node/211517
http://drupal.org/node/981794
Please, can someone document this new hook to allow torotil to commit it soon?
Thank you!
Comment #26
m1n0 commentedHere is a patch #18 with added simple documentation in votingapi.api.php.
Comment #27
chefnelone commentedPlease, can someone provide a example of how to use this hook once the pacth is applied.
As far as I see, no new condition is added, am I wrong?
Thanks.
Comment #28
m1n0 commentedThe last added patch adds documentation to votingapi.api.php - it contains very simple example how to use this new hook.
If module maintainer will ask for better/more comprehensive example, I can add it. Real usage is quite specific, but I am sure some general usage could be documented.
Comment #29
torotil commentedI've committed the last patch. Thanks to all for participating!
Comment #31
tahiticlic commentedWell, I guess you have to review votingapi.api.php in order to replace
hook_votingapi_preset_votes example by hook_votingapi_preset_votes_alter