diff --git a/includes/webform.pages.inc b/includes/webform.pages.inc
index f75250b..7d3fb03 100644
--- a/includes/webform.pages.inc
+++ b/includes/webform.pages.inc
@@ -79,7 +79,7 @@ function webform_configure_form($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/config/content/webform'))),
);
@@ -108,6 +108,38 @@ function webform_configure_form($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'),
@@ -277,6 +309,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'];
@@ -331,3 +373,26 @@ function theme_webform_advanced_submit_limit_form($variables) {
return drupal_render_children($form);
}
+
+/**
+ * Theme the total submit limit fieldset on the webform node form.
+ */
+function theme_webform_advanced_total_submit_limit_form($variables) {
+ $form = $variables['form'];
+ $form['total_submit_limit']['#attributes']['class'] = array('webform-set-active');
+ $form['total_submit_interval']['#attributes']['class'] = array('webform-set-active');
+ // Remove div wrappers around limit options.
+ $form['total_submit_limit']['#theme_wrappers'] = array();
+ $form['total_submit_interval']['#theme_wrappers'] = array();
+ $replacements = array(
+ '!count' => drupal_render($form['total_submit_limit']),
+ '!timespan' => drupal_render($form['total_submit_interval']),
+ );
+
+ $form['enforce_total_limit']['no']['#theme_wrappers'] = array('webform_inline_radio');
+ $form['enforce_total_limit']['yes']['#title'] = NULL;
+ $form['enforce_total_limit']['yes']['#inline_element'] = t('Limit to !count submission(s) !timespan', $replacements);
+ $form['enforce_total_limit']['yes']['#theme_wrappers'] = array('webform_inline_radio');
+
+ return drupal_render_children($form);
+}
diff --git a/includes/webform.submissions.inc b/includes/webform.submissions.inc
index 86b00c6..f12c59e 100644
--- a/includes/webform.submissions.inc
+++ b/includes/webform.submissions.inc
@@ -843,6 +843,42 @@ 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 from the database.
+ $query = db_select('webform_submissions')
+ ->condition('nid', $node->nid)
+ ->condition('is_draft', 0);
+
+ if ($node->webform['total_submit_interval'] != -1) {
+ $query->condition('submitted', REQUEST_TIME - $node->webform['total_submit_interval'], '>');
+ }
+
+ // Fetch all the entries from the database within the submit interval.
+ $num_submissions_database = $query->countQuery()->execute()->fetchField();
+
+ 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 45d85e0..a80b24e 100644
--- a/webform.install
+++ b/webform.install
@@ -97,6 +97,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'),
);
@@ -692,3 +704,16 @@ function webform_update_7315() {
db_add_field('webform_last_download', 'requested', array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, 'default' => 0,));
}
}
+
+/**
+ * Add additional columns for total submission limit.
+ */
+function webform_update_7316() {
+ if (!db_field_exists('webform', 'total_submit_limit')) {
+ db_add_field('webform', 'total_submit_limit', array('type' => 'int', 'not null' => TRUE, 'default' => -1));
+ }
+
+ if (!db_field_exists('webform', 'total_submit_interval')) {
+ db_add_field('webform', 'total_submit_interval', array('type' => 'int', 'not null' => TRUE, 'default' => -1));
+ }
+}
diff --git a/webform.module b/webform.module
index 7c90051..a4ff97a 100644
--- a/webform.module
+++ b/webform.module
@@ -525,7 +525,7 @@ function webform_theme() {
'render element' => 'webform',
),
'webform_view_messages' => array(
- 'variables' => array('node' => NULL, 'teaser' => NULL, 'page' => NULL, 'submission_count' => NULL, 'limit_exceeded' => NULL, 'allowed_roles' => NULL, 'closed' => NULL, 'cached' => NULL),
+ 'variables' => array('node' => NULL, 'teaser' => NULL, 'page' => NULL, 'submission_count' => NULL, 'limit_exceeded' => NULL, 'total_limit_exceeded' => NULL, 'allowed_roles' => NULL, 'closed' => NULL, 'cached' => NULL),
),
'webform_form' => array(
'render element' => 'form',
@@ -602,6 +602,10 @@ function webform_theme() {
'render element' => 'form',
'file' => 'includes/webform.pages.inc',
),
+ 'webform_advanced_total_submit_limit_form' => array(
+ 'render element' => 'form',
+ 'file' => 'includes/webform.pages.inc',
+ ),
// webform.report.inc.
'webform_results_per_page' => array(
'variables' => array('total_count' => NULL, 'pager_count' => NULL),
@@ -1136,6 +1140,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'),
@@ -1381,6 +1387,17 @@ function webform_node_view($node, $view_mode) {
}
}
+ // 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) {
@@ -1403,7 +1420,7 @@ function webform_node_view($node, $view_mode) {
// Print out messages for the webform.
if (empty($node->in_preview) && !isset($node->webform_block) && !$logging_in) {
- theme('webform_view_messages', array('node' => $node, 'teaser' => $teaser, 'page' => $page, 'submission_count' => $submission_count, 'limit_exceeded' => $limit_exceeded, 'allowed_roles' => $allowed_roles, 'closed' => $closed, 'cached' => $cached));
+ theme('webform_view_messages', array('node' => $node, 'teaser' => $teaser, 'page' => $page, 'submission_count' => $submission_count, 'limit_exceeded' => $limit_exceeded, 'total_limit_exceeded' => $total_limit_exceeded, 'allowed_roles' => $allowed_roles, 'closed' => $closed, 'cached' => $cached));
}
// Add the output to the node.
@@ -1453,6 +1470,8 @@ function theme_webform_view($variables) {
* 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
@@ -1466,6 +1485,7 @@ function theme_webform_view_messages($variables) {
$page = $variables['page'];
$submission_count = $variables['submission_count'];
$limit_exceeded = $variables['limit_exceeded'];
+ $total_limit_exceeded = $variables['total_limit_exceeded'];
$allowed_roles = $variables['allowed_roles'];
$closed = $variables['closed'];
$cached = $variables['cached'];
@@ -1511,6 +1531,14 @@ function theme_webform_view_messages($variables) {
}
$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) {
@@ -2032,6 +2060,19 @@ function webform_client_form_validate($form, &$form_state) {
}
}
+ // Check that the submissions have not exceeded the total submission limit.
+ if ($node->webform['total_submit_limit'] != -1) {
+ module_load_include('inc', 'webform', 'includes/webform.submissions');
+ // Check if the total number of entries was reached before the user submitted
+ // the form.
+ if (!$finished && _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);
+ form_set_error('', NULL);
+ return;
+ }
+ }
+
// Run all #element_validate and #required checks. These are skipped initially
// by setting #validated = TRUE on all components when they are added.
_webform_client_form_validate($form, $form_state);