For a small surf music and skate festival, we're trying to allow people to participate in different workshops. However, we prefer people not to subscribe twice to the same TYPE of workshop.

With node registration, there's of course the option to limit the user to 1 registration, which works for one time slot.
But every time slot of the workshops is a different node.
The workshops have a taxonomy term to indicate their type.

So: how should/could I customize this module, so that it allows for only one registration per taxonomy type? :)

PS: this festival is made possible by volunteers. I'm not getting paid for this; any help is welcome :)

Comments

rudiedirkx’s picture

Issue tags: -taxonomy

Implement hook_node_registration_access() (to hide form and page/tab) or hook_form_node_registration_form_alter() to add a custom validation error/message.

Jelmer85’s picture

Thanks! Sounds both good.
I'm not exactly a drupal ninja when it comes to modules/coding. Any suggestions as to how to see if the user already has the current taxonomy tag in one of his registrations?
If I manage to create the code, i'll post it of course to share..

Jelmer85’s picture

Another option would be to allow users only to register for one content type. Would that be easier maybe?

rudiedirkx’s picture

That would require the same kind of validation, so it's not much easier =) The query to check would be easier though. How many content types would you have to make? The taxonomy term solution is cleaner IMO, but maybe more difficult.

If you use the taxonomy terms:

1. Fetch all nids from nodes that have this term, using an EntityFieldQuery
2. Fetch all registrations from this user with these nids
3. If there are any, they have already registered for this type

If you use the content types:

1. Fetch all nids from all nodes from this type, using a very simple query directly on the node table
2. Step 2 and 3 from above

Goodluck

Jelmer85’s picture

Hmm, I'm running into problems (lack of knowledge). Not all has to do with NR though, so I understand if you can't be bothered :D

1. Not sure when to start my module (currently i have: function limit_registrations_by_taxonomy_field_attach_submit($node){ )
In the docs the maker suggests "node_registration_submit". But AFAIK this is not a hook, so how to use that?
2. I managed to get all nodes with a taxonomy term, but can't figure out how to get the page's current term.
3. Not sure how to fetch all node registrations for a given userid. Should I use _node_registration_user_registered($node, $account) ?
4. How to make node_registrations stop registering a user, when my code indicates that yes indeed this user was already registrered for this term..

rudiedirkx’s picture

1. Submit is too late. You could use validate. It's not very friendly to error after filling out the form though, so you should error before, or just not show the form at all. See #1 for method.
2. $node->field_term['und']['0']['tid']; should work if you have the node... Get the node with menu_get_object('node') otherwise.
3. No, that function will only fetch for 1 event. You need a custom query on table {node_registration}.
4. I'd implement hook_node_registration_access() to deny those users access to the form. Otherwise use a custom validator (see 1.) and set_form_error()

Goodluck =)

Alternatively, if programming is not your thing, you could try Rules. It should have good support, but it's still very tricky, because you're doing a tricky thing.

Jelmer85’s picture

Programming is not my thing yét ;)

right now, I have difficulty using
hook_node_registration_access($registration, $op, $account, $reason) {

The description of the parameters is not completely clear to me:
$registration - it is a new registration, so no id yet. So what do I pass to the function?

so far I've got something like:

function limit_registrations_by_taxonomy_node_registration_access(null,'add',$account->uid;) {
 if($alreadyregistrered){
return FALSE;
}
}
Jelmer85’s picture

Solved it! :)

function limit_registrations_by_taxonomy_node_registration_access(){      
    //load current node
    $node = menu_get_object('node');
    //load current taxonomy term
    $currentTaxId = $node->field_type_clinic['und']['0']['tid'];
    
    //get all the nodeid's that contain the taxonomy terms from the current page
    $nodesToCheck = taxonomy_select_nodes($currentTaxId,FALSE,FALSE);
        
    //loop over the taxonomy id's and check for registrations. Return FALSE if any registration is found.
    foreach ($nodesToCheck as &$value) {
        if(_node_registration_user_registered(node_load($value))){
            dpm("al ingeschreven voor ".$value."!");
            return FALSE;
        }
    } 
}

Only thing left: how to set the hook propperly, so that a message instead of a ? is displayed to the user.
function hook_node_registration_access($registration, $op, $account, $reason)
I don't know what to set for $registration, $op, $account, as it all seems to work without providing those? I want however to set $reason..

Jelmer85’s picture

Issue summary: View changes
Jelmer85’s picture

Final:
not solved:

  • message to explain the user why he can't register, instead of the questionmark

prerequisites:

  • you need a taxonomy field on the workshops page and use the right machine name. In this case it's called field_type_clinic
function limit_registrations_by_taxonomy_node_registration_access(){
    //load current node
    $node = menu_get_object('node');
    
    
    if(isset($node->field_type_clinic['und']['0']['tid'])){
        
        //load current taxonomy term
        $currentTaxId = $node->field_type_clinic['und']['0']['tid'];
        
        //get all the nodeid's that contain the taxonomy terms from the current page
        $nodesToCheck = taxonomy_select_nodes($currentTaxId,FALSE,FALSE);
            
        //loop over the taxonomy id's and check for registrations. Return FALSE if any registration is found.
        foreach ($nodesToCheck as &$value) {
            if(_node_registration_user_registered(node_load($value))){
                //dpm("already subscribed for ".$value."!");
                //user should not be able to register
                return FALSE;
                //return $reason = "You can only register for one workshop.";
            }
        }
    }
}

rudiedirkx’s picture

That's pretty clever, using taxonomy_select_nodes(). You should use the NR hook params though: one is $registration and it has a property $registration->node, which you're supposed to use instead of menu_get_object().