PHP snippet for limiting the total number of submissions to a Webform. Note that this is different from limiting the number of submissions per user, which is already an option in the webform configuration.

This snippet counts the number of submissions and when the max is reached, all roles for the node are automatically unchecked and the node is saved, thereby denying access to the form. This code is built on this post by quicksketch.

  // Count the number of submissions in the webform_submissions table for this node.
  $count = db_result(db_query("SELECT count(*) FROM {webform_submissions} WHERE nid = %d", $node->nid));

  // The submission limit is 20 - if it has been exceeded...
  if ($count >= 20) {
    // Uncheck all role access for this node. This disables access so users will see
    // this message when they navigate to the form: 'Submissions for this form are closed.'
    $node->webform['roles'] = array();
    
    // Save the node with all roles unchecked
    node_save($node);
  }

The next user that visits the form will receive the message "Submissions for this form are now closed.", which is the default behavior of Webform when no roles have access to submit the form.

Comments

ln282’s picture

My site uses forms to allow people to claim a limited number of tickets for an event, and I needed to close the form when the tickets are gone. With the help I got here: http://drupal.org/node/532208 , I was able to put together this code snippet for advanced validation:

 // Get the value of the relevant field from the form being currently submitted.
$total_attending = $form['submitted']['total_attending']['#value'];
 // Sum the total for the relevant field in the webform_submitted_data table for this node.
  $count = db_result(db_query("SELECT sum(data) FROM {webform_submitted_data} WHERE nid = %d AND cid = 7", $node->nid)) + $total_attending;

  // The submission limit is 125 - if it has been exceeded...
  if ($count >= 125) {
    // Uncheck all role access for this node. This disables access so users will see
    // this message when they navigate to the form: 'Registrations are no longer being accepted as this event is full. Thank you for your interest.'
    $node->webform['roles'] = array();
   
    // Save the node with all roles unchecked
    node_save($node);
  }

The "cid" is the number of the field you're totaling over all submissions, based on the order it was added to the form, not the order it's displayed. Adding the value for the field of the form being currently submitted is key, or the form will allow one more registration than it should.

flaviovs’s picture

Using the API to query for the number of submissions is preferred:

$count = webform_get_submission_count($node->nid);
webform_get_submission_count($nid, $uid = NULL):
/**
 * Return a count of the total number of submissions for a node.
 *
 * @param $nid
 *   The node ID for which submissions are being fetched.
 * @param $uid
 *   Optional; the user ID to filter the submissions by.
 * @return
 *   An integer value of the number of submissions.
 */
Rob C’s picture

For Drupal 7:

$count = db_query("SELECT sum(data) FROM {webform_submitted_data} ... etc ... WHERE cid = 7")->fetchField();

Use fetchField, db_result is no more.