diff --git a/includes/webform.pages.inc b/includes/webform.pages.inc
index f6295dd..040d1a9 100644
--- a/includes/webform.pages.inc
+++ b/includes/webform.pages.inc
@@ -83,7 +83,7 @@ function webform_configure_form(&$form_state, $node) {
// Submission limit settings.
$form['submission']['submit_limit'] = array(
'#type' => 'item',
- '#title' => t('Submission limit'),
+ '#title' => t('Submission limit per user'),
'#theme' => 'webform_advanced_submit_limit_form',
'#description' => t('Limit the number of submissions per user. A user is identified by their user login if logged-in, or by their IP Address and Cookie if anonymous. Use of cookies may be modified in the global Webform settings.', array('!url' => url('admin/settings/webform'))),
);
@@ -112,6 +112,38 @@ function webform_configure_form(&$form_state, $node) {
'#parents' => array('submit_interval'),
);
+ // Submission limit settings for all submissions.
+ $form['submission']['total_submit_limit'] = array(
+ '#type' => 'item',
+ '#title' => t('Total Submissions limit'),
+ '#theme' => 'webform_advanced_total_submit_limit_form',
+ '#description' => t('Limit the total number of allowed submissions.'),
+ );
+ $form['submission']['total_submit_limit']['enforce_total_limit'] = array(
+ '#type' => 'radios',
+ '#options' => array('no' => t('Unlimited'), 'yes' => 'Limit to !count submission(s) !timespan'),
+ '#default_value' => $node->webform['total_submit_limit'] == -1 ? 'no' : 'yes',
+ '#parents' => array('enforce_total_limit'),
+ );
+ $form['submission']['total_submit_limit']['total_submit_limit'] = array(
+ '#type' => 'textfield',
+ '#maxlength' => 8,
+ '#size' => 8,
+ '#default_value' => $node->webform['total_submit_limit'] != -1 ? $node->webform['total_submit_limit'] : '',
+ '#parents' => array('total_submit_limit'),
+ );
+ $form['submission']['total_submit_limit']['total_submit_interval'] = array(
+ '#type' => 'select',
+ '#options' => array(
+ '-1' => t('ever'),
+ '3600' => t('every hour'),
+ '86400' => t('every day'),
+ '604800' => t('every week'),
+ ),
+ '#default_value' => $node->webform['total_submit_interval'],
+ '#parents' => array('total_submit_interval'),
+ );
+
$form['submission']['status'] = array(
'#type' => 'radios',
'#title' => t('Status of this form'),
@@ -281,6 +313,16 @@ function webform_configure_form_submit($form, &$form_state) {
$node->webform['submit_interval'] = $form_state['values']['submit_interval'];
}
+ // Set the total submit limit to -1 if set to unlimited.
+ if ($form_state['values']['enforce_total_limit'] == 'no') {
+ $node->webform['total_submit_limit'] = -1;
+ $node->webform['total_submit_interval'] = -1;
+ }
+ else {
+ $node->webform['total_submit_limit'] = $form_state['values']['total_submit_limit'];
+ $node->webform['total_submit_interval'] = $form_state['values']['total_submit_interval'];
+ }
+
// Set submit notice.
$node->webform['submit_notice'] = $form_state['values']['submit_notice'];
@@ -308,6 +350,21 @@ function theme_webform_advanced_submit_limit_form($form) {
}
/**
+ * Theme the total submit limit fieldset on the webform node form.
+ */
+function theme_webform_advanced_total_submit_limit_form($form) {
+ $form['total_submit_limit']['#attributes']['class'] = 'webform-set-active';
+ $form['total_submit_interval']['#attributes']['class'] = 'webform-set-active';
+ // Remove div wrappers around limit options.
+ $replacements = array(
+ '!count' => preg_replace('/(
]*>)(.*?)(<\/div>)/s', '$2', drupal_render($form['total_submit_limit'])),
+ '!timespan' => preg_replace('/(
]*>)(.*?)(<\/div>)/s', '$2', drupal_render($form['total_submit_interval'])),
+ );
+ $form['enforce_total_limit']['yes']['#title'] = t('Limit to !count submission(s) !timespan', $replacements);
+ return drupal_render($form);
+}
+
+/**
* Theme the redirection setting on the webform node form.
*/
function theme_webform_advanced_redirection_form($form) {
diff --git a/includes/webform.submissions.inc b/includes/webform.submissions.inc
index 97fc68c..8290723 100644
--- a/includes/webform.submissions.inc
+++ b/includes/webform.submissions.inc
@@ -790,6 +790,38 @@ function _webform_submission_limit_check($node) {
}
/**
+ * Check if the total number of submissions has exceeded the limit on this form.
+ *
+ * @param $node
+ * The webform node to be checked.
+ * @return
+ * Boolean TRUE if the form has exceeded it's limit. FALSE otherwise.
+ */
+function _webform_total_submission_limit_check($node) {
+
+ // Check if submission limiting is enabled.
+ if ($node->webform['total_submit_limit'] == '-1') {
+ return FALSE; // No check enabled.
+ }
+
+ // Retrieve submission data for this IP address or username from the database.
+ $query = 'SELECT count(*) ' .
+ 'FROM {webform_submissions} ' .
+ 'WHERE submitted > %d AND nid = %d AND is_draft = 0';
+
+ // Fetch all the entries from the database within the submit interval with this username and IP.
+ $num_submissions_database = db_result(db_query($query, ($node->webform['total_submit_interval'] != -1) ? (time() - $node->webform['total_submit_interval']) : $node->webform['total_submit_interval'], $node->nid));
+
+ if ($num_submissions_database >= $node->webform['total_submit_limit']) {
+ // Limit exceeded.
+ return TRUE;
+ }
+
+ // Limit not exceeded.
+ return FALSE;
+}
+
+/**
* Preprocess function for webform-submission.tpl.php.
*/
function template_preprocess_webform_submission(&$vars) {
diff --git a/webform.install b/webform.install
index 1740e76..f98e53e 100644
--- a/webform.install
+++ b/webform.install
@@ -98,6 +98,18 @@ function webform_schema() {
'not null' => TRUE,
'default' => -1,
),
+ 'total_submit_limit' => array(
+ 'description' => 'The total number of submissions allowed within an interval. -1 is unlimited.',
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => -1,
+ ),
+ 'total_submit_interval' => array(
+ 'description' => 'The amount of time in seconds that must pass before another submission can be submitted within the set limit.',
+ 'type' => 'int',
+ 'not null' => TRUE,
+ 'default' => -1,
+ ),
),
'primary key' => array('nid'),
);
@@ -1384,6 +1396,22 @@ function webform_update_6328() {
}
/**
+ * Add additional columns for total submission limit.
+ */
+function webform_update_6329() {
+ $ret = array();
+ if (!db_column_exists('webform', 'total_submit_limit')) {
+ db_add_field($ret, 'webform', 'total_submit_limit', array('type' => 'int', 'not null' => TRUE, 'default' => -1));
+ }
+
+ if (!db_column_exists('webform', 'total_submit_interval')) {
+ db_add_field($ret, 'webform', 'total_submit_interval', array('type' => 'int', 'not null' => TRUE, 'default' => -1));
+ }
+
+ return $ret;
+}
+
+/**
* Recursively delete all files and folders in the specified filepath, then
* delete the containing folder.
*
diff --git a/webform.module b/webform.module
index 9a3226d..35c0d70 100644
--- a/webform.module
+++ b/webform.module
@@ -584,6 +584,10 @@ function webform_theme() {
'arguments' => array('form' => NULL),
'file' => 'includes/webform.pages.inc',
),
+ 'webform_advanced_total_submit_limit_form' => array(
+ 'arguments' => array('form' => NULL),
+ 'file' => 'includes/webform.pages.inc',
+ ),
// webform.report.inc.
'webform_results_per_page' => array(
'arguments' => array('total_count' => NULL, 'pager_count' => NULL),
@@ -1095,6 +1099,8 @@ function webform_node_defaults() {
'submit_text' => '',
'submit_limit' => '-1',
'submit_interval' => '-1',
+ 'total_submit_limit' => '-1',
+ 'total_submit_interval' => '-1',
'status' => '1',
'record_exists' => FALSE,
'roles' => array('1', '2'),
@@ -1310,6 +1316,17 @@ function webform_node_view(&$node, $teaser, $page) {
}
}
+ // Check if the user can add another submission if there is a limit on total
+ // submisions.
+ if ($node->webform['total_submit_limit'] != -1) { // -1: Submissions are never throttled.
+ module_load_include('inc', 'webform', 'includes/webform.submissions');
+
+ // Disable the form if the limit is exceeded and page cache is not active.
+ if (($total_limit_exceeded = _webform_total_submission_limit_check($node)) && !$cached) {
+ $enabled = FALSE;
+ }
+ }
+
// Check if this user has a draft for this webform.
$is_draft = FALSE;
if (($node->webform['allow_draft'] || $node->webform['auto_save']) && $user->uid != 0) {
@@ -1333,7 +1350,7 @@ function webform_node_view(&$node, $teaser, $page) {
// Print out messages for the webform.
if ($node->build_mode != NODE_BUILD_PREVIEW && !isset($node->webform_block) && !$logging_in) {
- theme('webform_view_messages', $node, $teaser, $page, $submission_count, $limit_exceeded, $allowed_roles, $closed, $cached);
+ theme('webform_view_messages', $node, $teaser, $page, $submission_count, $limit_exceeded, $total_limit_exceeded, $allowed_roles, $closed, $cached);
}
if (isset($output)) {
@@ -1379,6 +1396,8 @@ function theme_webform_view($node, $teaser, $page, $form, $enabled) {
* for anonymous users.
* @param $limit_exceeded
* Boolean value if the submission limit for this user has been exceeded.
+ * @param $total_limit_exceeded
+ * Boolean value if the total submission limit has been exceeded.
* @param $allowed_roles
* A list of user roles that are allowed to submit this webform.
* @param $closed
@@ -1390,7 +1409,7 @@ function theme_webform_view($node, $teaser, $page, $form, $enabled) {
* is cached, such as "Submissions for this form are closed", because they
* apply to all users equally.
*/
-function theme_webform_view_messages($node, $teaser, $page, $submission_count, $limit_exceeded, $allowed_roles, $closed, $cached) {
+function theme_webform_view_messages($node, $teaser, $page, $submission_count, $limit_exceeded, $total_limit_exceeded, $allowed_roles, $closed, $cached) {
global $user;
$type = 'status';
@@ -1434,6 +1453,14 @@ function theme_webform_view_messages($node, $teaser, $page, $submission_count, $
}
$type = 'error';
}
+ elseif ($total_limit_exceeded && !$cached) {
+ if ($node->webform['total_submit_interval'] == -1 && $node->webform['total_submit_limit'] > 1) {
+ $message = t('This form has received the maximum number of entries.');
+ }
+ else {
+ $message = t('You may not submit another entry at this time.');
+ }
+ }
// If the user has submitted before, give them a link to their submissions.
if ($submission_count > 0 && $node->webform['submit_notice'] == 1 && !$cached) {
@@ -2174,6 +2201,14 @@ function webform_client_form_submit($form, &$form_state) {
$node = $form['#node'];
$sid = $form_state['values']['details']['sid'] ? (int) $form_state['values']['details']['sid'] : NULL;
+ // Check if the total number of entries was reached before the user submitted
+ // the form.
+ if (_webform_total_submission_limit_check($node)) {
+ // Show the user the limit has exceeded.
+ drupal_set_message('While you were filling out the form the maximum number of submissions has been reached.', 'error', FALSE);
+ return;
+ }
+
// Check if user is submitting as a draft.
$is_draft = (int) !empty($form_state['save_draft']);