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

Taxoman’s picture

Subscribing (coming from #981794: condition for "user has already voted on node", comment 5)

jessepinho’s picture

Subscribing as well. Would love to have this feature.

EDIT: Oops; didn't notice the Follow feature. Sweet!

aminalid’s picture

I would like to have this feature as well.

Taxoman’s picture

Priority: Normal » Major
BeaPower’s picture

sub, even to hide the rating fields so that user can leave an ordinary comment if voted

Steven Brown’s picture

So 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.

<?php
function votingapi_add_votes(&$votes) {
  if (!empty($votes['entity_id'])) {
    $votes = array($votes);
  }
  $function = variable_get('votingapi_storage_module', 'votingapi') . '_votingapi_storage_add_vote';
  foreach ($votes as $key => $vote) {
    _votingapi_prep_vote($vote);
    $function($vote);
    $votes[$key] = $vote;
  }
  module_invoke_all('votingapi_insert', $votes);
  return $votes;
}
?>
davidcsonka’s picture

Subscribing -

This is a critical mechanism for preventing the most basic of exploitations of a voting/points system - "stuffing the ballot box".

BeaPower’s picture

Same here, what is the update on this?

Steven Brown’s picture

I 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.

blackclover’s picture

subscribe

m1n0’s picture

What is the status on this? I am using d6 version but I have the same problem.

m1n0’s picture

Version: 7.x-2.x-dev » 6.x-2.3
Category: feature » bug
StatusFileSize
new898 bytes

I 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.

mermemladeK’s picture

Bump! I am looking for this exact in thing in D7.

torotil’s picture

Version: 6.x-2.3 » master
Assigned: Unassigned » torotil
Category: bug » feature

This 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.

istryker’s picture

I 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.

istryker’s picture

I notice one problem with this issue, and I might rename it's title.

What happens when you try to cast a vote

  • Call Voteapi_set_votes()
    • Find and delete vote(s)
    • Add new vote(s)

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).

istryker’s picture

Title: Add Pre-insert hook or save vote data from previous users votes » Add pre-save or pre-set hook before data is store to database
Status: Active » Needs review
StatusFileSize
new517 bytes

Attached 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

istryker’s picture

StatusFileSize
new685 bytes

So the previous patch does not allow pass by reference. If a module want to unset a vote, they cannot. Switch
module_invoke_all() to drupal_alter()

raphael apard’s picture

i'm using this patch. presave hook can be usefull.

raphael apard’s picture

Title: Add pre-save or pre-set hook before data is store to database » Add pre-save or pre-set hook before data is store to database (D7)
Version: master » 7.x-2.x-dev
Assigned: torotil » Unassigned
StatusFileSize
new692 bytes

Here the patch for D7 version.
My bad, patch #18 works fine.

Use hook_votingapi_preset_votes_alter()

raphael apard’s picture

Title: Add pre-save or pre-set hook before data is store to database (D7) » Add pre-save or pre-set hook before data is store to database
Version: 7.x-2.x-dev » master
istryker’s picture

Status: Needs review » Reviewed & tested by the community

@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.

raphael apard’s picture

@iStryker, yes it was a mistake. Patch #18 works fine.

torotil’s picture

Status: Reviewed & tested by the community » Needs work

We'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.

mxt’s picture

Other 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!

m1n0’s picture

Status: Needs work » Needs review
StatusFileSize
new1.69 KB

Here is a patch #18 with added simple documentation in votingapi.api.php.

chefnelone’s picture

Please, 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.

m1n0’s picture

The 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.

torotil’s picture

Status: Needs review » Fixed

I've committed the last patch. Thanks to all for participating!

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

tahiticlic’s picture

Well, I guess you have to review votingapi.api.php in order to replace
hook_votingapi_preset_votes example by hook_votingapi_preset_votes_alter