Docs & Support

Learn about all the Formidable features and get support from our amazing customer success team.

frm_validate_entry

This hook allows you to add custom errors that are not specific to one field.

Usage

add_filter('frm_validate_entry', 'validate_my_form', 20, 2);

Formidable Forms makes advanced site building simple. Launch forms, directories, dashboards, and custom WordPress apps faster than ever before.

Parameters

  • $errors (array)
  • $posted_values (array)

Examples

Remove all errors

Use this code to remove all errors from a form if a field has a particular value.

add_filter('frm_validate_entry', 'validate_my_form', 20, 2);
function validate_my_form($errors, $values){
  if ( $values['form_id'] == 45 && $_POST['item_meta'][125] != 'Yes' ) { //Change 45 to the ID of your form, 125 to the ID of a field, and 'Yes' to any value
    return array();
  }
return $errors;
}

Basic format

Use this format if you would like to add an error to the form.

add_filter('frm_validate_entry', 'validate_my_form', 20, 2);
function validate_my_form($errors, $values){
  if($values['form_id'] == 45){//Change 45 to the ID of your form and add additional conditions here
    $errors['my_error'] = 'You are not allowed to submit this form.';//Change this to your error
  }
return $errors;
}

Customize the spam message

add_filter('frm_validate_entry', 'validate_my_form', 20, 2);
function validate_my_form($errors, $values){
  if ( isset($errors['spam']) ) {
    $errors['spam'] = 'No submissions for you!';
  }
return $errors;
}

Require one field from a set

Make sure one of the fields in a group of fields is required.

add_filter('frm_validate_entry', 'check_phone_fields', 10, 2);
function check_phone_fields( $errors, $values ) {
  if ( $values['form_id'] == 45 ) { // change 45 to your form id
    $group_fields = array(25, 26, 27); // change 25, 26, 27 to the ids of your fields
    foreach ( $group_fields as $field_id ) {
      if ( $_POST['item_meta'][$field_id] != '' ) {
        return $errors; // do not continue checking if any of these fields have a value
      }
    }
    foreach ( $group_fields as $field_id ) {
      $errors['field'. $field_id] = 'Please fill in one of the fields.';
    }
  }
  return $errors;
}

Prevent submissions from an IP

Blacklist any IPs and prevent entries from being created.

add_filter('frm_validate_entry', 'frm_check_ip_blacklist', 10, 2);
function frm_check_ip_blacklist( $errors, $values ) {
  $ips = array( '107.150.42.226', '195.154.232.138', '155.108.70.195' );
  $current_ip = FrmAppHelper::get_ip_address();
  if ( in_array( $current_ip, $ips ) ) {
    $errors['spam'] = 'You are not allowed to do that';
  }
  return $errors;
}

Populate fields from User ID

Fill other fields based on the id of the user selected in your user ID field.

add_filter('frm_validate_entry', 'frm_add_user_name', 20, 2);
function frm_add_user_name( $errors, $values ) {
  if ( isset( $_POST['item_meta'][25] ) ) { //change 25 to the id of the user id field
    $user = get_userdata( absint( $_POST['item_meta'][25] ) ); //change 25 here too
    $_POST['item_meta'][26] = $user->last_name; //change 26 to the id of the last name field
    $_POST['item_meta'][27] = $user->first_name; //change 27 to the id of the first name field
  }
  return $errors;
}

Limit submissions per time period (or any stat)

Limit form submissions to anything that can be determined by a stat. Examples:

  • 1 submission per user per week
  • 10 submissions from all users with "Platinum" selected in the membership field.
  • 100 submissions from all users per year
  • total of 10 votes per user
add_filter('frm_validate_entry', 'check_submitted', 20, 2);
function check_submitted($errors, $values){
	if  ( $values['form_id'] !== 30 ) {//Change 30 to the ID of your form 
		return $errors;
	}
	
	$entries_submitted = FrmProStatisticsController::stats_shortcode( array( 'id' => 182, 'type' => 'count', 'user_id' => 'current',  'created_at_greater_than' => 'Monday this week' ) );//change the params to the params of your stat

	if ( $entries_submitted >= 1 ){//change 1 to your limit number
		$errors['too_many'] = 'You have already submitted this form this week. You are most welcome to submit again next week.';//Change this to your error message
	}

	return $errors;
}

Recommendation: First, create the stat and test to make sure it's working as you want. Then, add the params to the code. For dates, you can use exact dates or relative dates. Read more about relative dates.

Save highest and lowest fields

This code example can be used when you have a group of fields with numeric values and you want to know which has the highest and lowest. The label of the highest will be stored in a field you designate, and the label of the lowest will be stored in another field you designate.

This could be used with, say, a personality quiz where the user gets scored on different categories. The user could be shown his/her strongest and weakest categories.

If two or more fields are tied for highest (or lowest), only one of them will be stored in the field.

Note: This code example requires PHP 7.3 or higher.

add_filter( 'frm_validate_entry', 'frm_save_highest_and_lowest', 20, 2 );
function frm_save_highest_and_lowest( $errors, $values ) {
   if ( $values['form_id'] !== 173 ) { // Change 173 to the id of your form.
      return $errors;
   }

   $fields                    = array( 2330, 2331, 2332, 2333, 2334 );// List the category field ids here.
   $highest_category_field_id = 2336;// Id of field that stores the highest category.
   $lowest_category_field_id  = 2338;// Id of field that stores the lowest category.

   $ordered_fields = array();

   foreach ( $fields as $field ) {
      if ( isset( $_POST['item_meta'][ $field ])){
         $ordered_fields[ $field ] = $_POST['item_meta'][ $field ];
      }
   }

   arsort( $ordered_fields );

   $highest_id    = array_key_first( $ordered_fields );
   $highest_field = FrmField::getOne( $highest_id );

   if ( ! empty( $highest_field ) ) {
      $_POST['item_meta'][ $highest_category_field_id ] = $highest_field->name;
   }

   $lowest_id    = array_key_last( $ordered_fields );
   $lowest_field = FrmField::getOne( $lowest_id );

   if ( ! empty( $lowest_field ) ) {
      $_POST['item_meta'][ $lowest_category_field_id ] = $lowest_field->name;
   }

   return $errors;
}

Limit event registration

Use this code to limit event registrations where people can register more than one person per entry in a form. If only one person can be registered per form, you can use the built-in entry limits setting for this.

This code shows an error message if the event has filled up while the person is filling out the form. It shows a different error message if the event still has remaining spots, but the user is trying to register more people than the available spots.

This code can be used nicely in conjunction with this code example, which hides a form based on the value in a stat. You can use a stat like the one used in this code example, with the id param equal to the id of the field that has the number of people registering for the event and type=total.

add_filter( 'frm_validate_entry', 'event_registration', 20, 2 );
function event_registration( $errors, $values ) {
	if ( $values['form_id'] !== 304 ) {//Change 304 to the ID of your form
		return $errors;
	}

	$registration_field = 3080;// Set this field to the id of the number of attendees field.
	$event_max          = 50;// Set this field to the maximum number of attendees for the event.

	$attendees     = (int) FrmProStatisticsController::stats_shortcode( array(
		'id'   => $registration_field,
		'type' => 'total'
	) );// Add extra params for your stat, if needed.
	$new_attendees = ( isset( $_POST['item_meta'][ $registration_field ] ) ) ? (int) $_POST['item_meta'][ $registration_field ] : 0;

	if ( $attendees >= $event_max ) {
		$errors['event_full'] = 'The event has just filled up. We hope you can join us next year.'; // Change this to the message you'd like to show if the event has filled up completely while the user has been filling out the form.
	} else if ( ( $attendees + $new_attendees ) > $event_max ) {
		$remaining_spaces          = $event_max - $attendees;
		$errors['not_enough_room'] = "Only {$remaining_spaces} spots are available for the event. You're most welcome to register up to {$remaining_spaces} people."; // Change this to the message you want to show if there are still spaces remaining, but the user has tried to register more people than there are spots available.
	}

	return $errors;
}

Change:

  • 304 to the id of your form
  • The registration field, 3080, to the id of the field where the number of people being registered is selected
  • The event max, 50, to the number of people who can attend the event
  • The 'event_full' message to the message you want to show when the event is completely full.
  • The 'not_enough_room' message to the message you want to show when the event still has spots available, but the person is trying to register more people than the available spots.

Remove errors in the admin

This code example removes errors when an entry is being created or edited in the admin area of the site. This can be especially useful in situations where you want to create entries without filling out all the required fields for testing purposes. Replace 99 with the ID of your form.

add_filter('frm_validate_entry', 'remove_errors_in_admin_area', 20, 2);
function remove_errors_in_admin_area($errors, $values){
	if ( $values['form_id'] == 99 && is_admin() ) { //Change 99 to the ID of your form
		return array();
	}
	return $errors;
}

Add unique validation when saving drafts

add_filter('frm_validate_entry', 'validate_unique_field', 10, 2 );
function validate_unique_field( $errors, $values ) {
    if ( ! FrmProFormsHelper::saving_draft() ) {
        return $errors;
    }

    $field_id = 795; // change this to the ID of the unique field
    if ( ! isset( $values['item_meta'][ $field_id ] ) ) {
        return $errors;
    }

    $entry_id = ! empty( $values['id'] ) ? $values['id'] : false;
    $value = $values['item_meta'][ $field_id ];
    if ( FrmProEntryMetaHelper::value_exists( $field_id, $value, $entry_id ) ) {
        $frm_settings = FrmAppHelper::get_settings();
        $errors[ 'field' . $field_id ] = "This field must be unique"; //Change this to your error message
    }	

    return $errors;
}

Remove spam bot error when there is no IP

Use this code snippet if you want to submit entries with no IP.

add_filter( 'frm_validate_entry', 'remove_spam_error' );
function remove_spam_error( $errors ) {
	if ( ! array_key_exists( 'spam', $errors ) || FrmAppHelper::get_ip_address() ) {
		return $errors;
	}

	if ( __( 'Your entry appears to be spam!', 'formidable' ) === $errors['spam'] ) {
		unset( $errors['spam'] );
	}

	return $errors;
}

Check nonce on form submission

By default, the nonce is unchecked on form submissions because of caching. It does include a nonce field in every form that can be checked by adding your own nonce check for a target form ID.

add_filter( 'frm_validate_entry', 'check_nonce_on_submit', 10, 2 );
function check_nonce_on_submit( $errors, $values ) {
	$target_form_id = 117; // Replace 117 with the ID of your form.
	if ( $target_form_id === $values['form_id'] && ! wp_verify_nonce( $values[ 'frm_submit_entry_' . $values['form_id'] ], 'frm_submit_entry_nonce' ) ) {
		$errors['nonce'] = 'CSRF attack blocked';
	}
	return $errors;
}

Allow submissions from allowlist of referrer URLs

Use this code example if you want to prevent a form loaded with an API script from being submitted from an unexpected site origin. This example applies to all types of forms but it would be more specifically easy to replicate anywhere for an API script.

add_filter('frm_validate_entry', 'allowlist_referrer_url' ,10, 2);
function allowlist_referrer_url( $errors, $values ) {
	$target_form_id = 215; // Change 215 to the ID of your form.

	if ( $target_form_id !== (int) $values['form_id'] ) {
		return $errors;
	}

	$referer           = FrmAppHelper::get_server_value( 'HTTP_REFERER' );
	$referer_allowlist = array( 'http://devsite.dev.formidableforms.com' ); //Change this.

	$blocked = true;
	foreach ( $referer_allowlist as $allowed_referer ) {
		if ( 0 === strpos( $referer, $allowed_referer ) ) {
			$blocked = false;
			break;
		}
	}

	if ( $blocked ) {
		$errors['referer_blocked'] = 'This form does not match the expected origin';
	}

	return $errors;
}

Generate custom entry key

Use this code example to generate a custom entry key for form entries, with a format set to seven digits.

add_filter('frm_validate_entry', 'generate_item_key', 20, 2);
function generate_item_key($errors, $values){
  if ( $values['form_id'] == 671 && $values['frm_action']== "create" ) { //Change 45 to the ID of your form
	  $validchars = '0123456789abcdefghijklmnopqrstuvwxyz'; //Change the string to your preferred characters
      $generatedkey = substr(str_shuffle($validchars), 0, 7); // Change 7 to the number of characters you want for the key
   $_POST['item_key']=$generatedkey;
  }
return $errors;
}

Generate slug for the View detail page

The detailed page uses the entry ID/key in a View by default. With this code snippet, you can set the entry key to get its value from another field in the form.

For example, if the business name is Formidable Forms, the entry key will be formidable-forms. It can then be used to generate a friendly URL for the View detail page.

add_filter('frm_validate_entry', 'key_as_slug', 20, 2);
function key_as_slug($errors, $values){
  if ( $values['form_id'] == 40) { //Change 40 to the ID of your form
	  $string = $_POST['item_meta'][21]; //change 21 to the ID of the first field (i.e. the business name field)
	  $count = FrmProStatisticsController::stats_shortcode( array( 'id'=> 21,'type'=> 'count','21'=> $string));
		if($count > 0)
		{
		  $string = $string."-".$count+1;
		}
      $myslug = strtolower(trim(preg_replace('/[^A-Za-z0-9-]+/', '-', $string), '-'));
   $_POST['item_key']=$myslug;
  }
return $errors;
}

Only display errors on the final page

Use this code example to only show errors when submitting the final page of a form. Typically, the required field validation will prevent you from going to the next page. This snippet allows you to change pages, and only when submitting the final page does it validate for errors.

add_filter('frm_validate_entry', 'display_errors_final_page', 10, 2);
function display_errors_final_page( $errors, $values ) {
	$target_form_id = 1381; //Replace 1381 with the ID of your form.
	if ( $target_form_id !== (int) $values['form_id'] ) {
		return $errors;
	}

	if ( FrmProFormsHelper::has_another_page( $target_form_id ) ) {
		$errors = array();
	}

	return $errors;
}

Implement spam blocking

Use this code example to implement spam blocking using the StopForumSpam API. It calls an API with the current user's IP address. If the API detects that the submission is spam, it will block the entry.

add_filter('frm_validate_entry', 'implement_spam_blocking', 10, 2);
function implement_spam_blocking( $errors, $values ) {
	$ip_address   = FrmAppHelper::get_ip_address();
	$ips_to_allow = array( '', '127.0.0.1'  );

	if ( ! in_array( $ip_address, $ips_to_allow, true ) ) {
		$response = wp_remote_get( 'http://api.stopforumspam.org/api?ip=' . $ip_address );
		$body     = wp_remote_retrieve_body( $response );

		if ( false !== strpos( $body, '<appears>yes</appears>' ) ) {
			$errors['spam'] = 'Your entry appears to be spam!';
		}
	}

	return $errors;
}

Allow email validation in spam filter

Use this code example to revise the API to support email validation in spam filter.

add_filter(
	'frm_validate_entry',
	function( $errors, $values ) {
		$ip_address   = FrmAppHelper::get_ip_address();
		$ips_to_allow = array( '', '127.0.0.1'  );

		if ( ! in_array( $ip_address, $ips_to_allow, true ) ) {
			$response = wp_remote_get( 'http://api.stopforumspam.org/api?ip=' . $ip_address );
			$body     = wp_remote_retrieve_body( $response );

			if ( false !== strpos( $body, '<appears>yes</appears>' ) ) {
				$errors['spam'] = 'Your entry appears to be spam!';
			}
		}

		foreach ( $values['item_meta'] as $value ) {
			if ( is_string( $value ) && is_email( $value ) ) {
				$response = wp_remote_get( 'http://api.stopforumspam.org/api?email=' . $value );
				$body     = wp_remote_retrieve_body( $response );

				if ( false !== strpos( $body, '<appears>yes</appears>' ) ) {
					$errors['spam'] = 'Your entry appears to be spam!';
				}
			}
		}

		return $errors;
	},
	10,
	2
);
Was this article helpful? *

This article may contain affiliate links. Once in a while, we earn commissions from those links. But we only recommend products we like, with or without commissions.

In this article

    We have a small, but amazing team of dedicated people who are committed to helping you achieve your goals and project requirements.


    Copyright © 2025 Strategy11, LLC. Formidable Forms® is a registered trademark Strategy11, LLC.

    Complete your purchase
    Special offer unlocked.
    Get 55% OFF!
    Complete Purchase
    Join 400,000+ using Formidable Forms to create form-focused solutions fast. Get Formidable Forms