1

I am trying to limit the creation of a node reference to 1 per user and per referenced node. More specifically: I have a content type named Debate and another one called Vote. Vote has a node reference field (from URL widget) called *debate_ref* to the Debate type. What i'm trying to achieve is for each user and for each debate to have only one vote i.e. when a user tries to create a 2nd vote node on the same debate node then he will recieve a message saying "You have already voted!".

"Unique field" module does the job but after the user attempts to save his 2nd vote node. What i would like to achieve is to deny access to the user who attempts to re-visit the "node/add/vote/nid" form if he has already voted for the specific debate.

Any help?

  • Do you use a custom module ? Or Panels at least ? I'm afraid you won't be able to do that without at least Panels. – Gregory Kapustin Feb 5 '13 at 14:42
  • Hi Greg. Well i created a costum module using the code from this link: drupal.stackexchange.com/questions/14504/… but i can't make it work. The panels idea sounds interesting. Can you please give me some feedback? – Billy Feb 5 '13 at 14:49
  • Feedback given as answer :) – Gregory Kapustin Feb 5 '13 at 15:49
  • How would users get to to node/add/vote/nid the second time? By typing it in manually? – Andy Feb 10 '13 at 18:17
  • Either manually or by clicking the corresponding "vote now" node reference link on each debate node. – Billy Feb 10 '13 at 18:27
2

A solution is to use hook on form_alter inside a custom module :

function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
 if($form_id == 'vote_node_form') {
    global $user;
    $nid = explode('/', current_path());
    $nid = end($nid);
    // I'm sure that next part can be done waaaaaaay better
    $query = db_select('node', 'n')
    ->condition('entity_type', 'vote', '=')
    ->condition('uid', $user->uid, '=');
    $query->join('your_entity_ref_field_table', 'e', 'n.nid = e.entity_id');
    $query->condition('your_reference_column', $nid, '=');
    $query->groupBy('e.entity_id')->execute();
    // I'd advice to do a dpm($query->fetchAssoc();) to check if I didn't make a mistake         :)

    if(!empty($query)) {
            // We force the user to go on any page if he has already casted a vote on that debate (you can i.e create a page with a word of explanation)
            drupal_goto('/');
            //or do whatever you want here
    } else {
            // If not, we let him go to the normal node creation page
    }
  }
}
|improve this answer|||||
  • Thanks again. I tried this in the template.php. My node reference field is: "field_debate_ref" with field table: field_data_field_debate ref and column: field_debate_ref_nid. I get errors each time i try to vote:PDOException: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM node n INNER JOIN field_data_field_debate_ref e ON n.entity_id = e.entity_' at line 1: SELECT FROM {node} n INNER JOIN {field_data_field_debate_ref} e ON n.entity_id..... – Billy Feb 8 '13 at 11:42
  • My bad : it's not n.entity_id = e.entity_id, it's n.nid = e.entity_id :) . I edited. – Gregory Kapustin Feb 8 '13 at 11:47
  • Sorry man. Still getting pdoexception error pointing at line 108 where the "$query->groupBy('e.entity_id')->execute();" is. I added the code i'm using at my initial question. Have a look maybe you'll get a clearer view. – Billy Feb 8 '13 at 12:21
  • maybe simply $query->groupBy(e.entity_id'); $query->execute(); – Gregory Kapustin Feb 8 '13 at 12:51
1

Maybe it's too late to change the specs, but have you considered using Flags with each flag counting as a vote? It seems to cover most of the uses you refer here.

|improve this answer|||||
1

Actually i'm just correcting Greg's code. So here it is:

function MYMODULE_form_alter(&$form, &$form_state, $form_id) {
if($form_id == 'vote_node_form') {
global $user;
$nid = explode('/', current_path());
$nid = end($nid);
$query = db_select('node', 'n')
->fields('n', array('nid'))
->condition('type', 'vote', '=')
->condition('uid', $user->uid, '=');
$query->join('field_data_field_debate_ref', 'e', 'n.nid = e.entity_id');
$query->condition('field_debate_ref_nid', $nid, '=');
$result = $query->groupBy('e.entity_id')->execute()->fetchField(); 
if(!empty($result)) {
        drupal_goto('/');
   } else {
  }
 }
}

It's working perfectly now limiting a vote node to 1 per user & per debate node. It can be used as a costum module or directly in template.php and the best (i think): as a php selector for a panel variant of the node/add form, with some minor changes of course.

The other solution is indeed the Flags module as mariomc mentions, but only the 3x dev branch where fields are permitted to be added to flags basically transforming them into content types that can be used for my purpose as votes, therefore having 1 vote per debate per user.

|improve this answer|||||
  • Great ! Sorry for all the errors on my original code :) – Gregory Kapustin Feb 10 '13 at 12:40
  • I'd be a bit careful with this code. It doesn't check $nid; it hardcodes field table names; it doesn't use EntityFieldQuery; it issues a drupal_goto() in a hook (potentially preventing other modules' hooks from firing). – Andy Feb 10 '13 at 18:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.