Code to ban URLs in form fields now triggers fatal error

For years I have used some code given by GF that prevents form submissions if URLs are included in specific (or any) form fields (to stop spam bots), but it has suddenly stopped working and now triggers a fatal error:

Fatal error : Uncaught TypeError: preg_match(): Argument #2 ($subject) must be of type string, array given in […]

Here is the code I was given, the line that is triggering the error is the one that starts with "if ( $result[‘is_valid’] "

add_filter( 'gform_field_validation', 'custom_validation', 10, 4 );
function custom_validation( $result, $value, $form, $field ) {

	if ( $result['is_valid'] && preg_match('/\b(?:(?:https?|ftp|http):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i', $value ) ) {
		$result['is_valid'] = false;
		$result['message'] = 'Please remove URLs';
	}
	return $result;
}

I found very similar code here that also does not work (triggers the same error):
https://community.gravityforms.com/t/how-to-block-link-tags-and-urls-hyperlinks-contained-in-any-form-field-regex-format-resolved/13787

Is there an updated way to stop users from submitting hyperlinks in form fields?

I am using the most current version of Gravity Forms with WP ver. 6.1.1 and PHP 8.0.

Any help would be appreciated!

There was probably a change in PHP 8 that causes a fatal error now. If you are checking all fields for URLs, you are probably checking some fields that return an array rather than a string. preg_match is looking for a string.

You will need to narrow the focus so that this validation filter only applies to specific fields in specific forms, or you will need to do more work to convert the parts of the array of values to string so the original function can work.

To apply to specific fields in one form, you could do this:

add_filter( 'gform_field_validation_8_2', 'custom_validation', 10, 4 );
add_filter( 'gform_field_validation_8_5', 'custom_validation', 10, 4 );
add_filter( 'gform_field_validation_8_6', 'custom_validation', 10, 4 );
add_filter( 'gform_field_validation_8_20', 'custom_validation', 10, 4 );
function custom_validation( $result, $value, $form, $field ) {
	if ( $result['is_valid'] && preg_match('/\b(?:(?:https?|ftp|http):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i', $value ) ) {
		$result['is_valid'] = false;
		$result['message'] = 'Please remove URLs';
	}
	return $result;
}

That would apply to fields 2, 5, 6, and 20 in form 8.

You could also change the code to check the field type before trying to validate. Something like this:

add_filter( 'gform_field_validation', 'custom_validation', 10, 4 );
function custom_validation( $result, $value, $form, $field ) {
	// check text fields and textareas for URLs
	if ( 'text' === $field->type || 'textarea' === $field->type ) {
		if ( $result['is_valid'] && preg_match('/\b(?:(?:https?|ftp|http):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i', $value ) ) {
			$result['is_valid'] = false;
			$result['message'] = 'Please remove URLs';
		}
	}
	return $result;
}

Got it, and thank you!!

Your explanation makes perfect sense. In our case, the bots and other (live?) spammers routinely fill the “message” field (textarea) with hyperlinks…so I will be sure to target just those textareas.

:slight_smile: and hugs,
Trisha

It will be easier then targeting only the textarea. You just need to add that check so that not all fields in the form as run through this filter, which is why there is a fatal error now (some values are not strings but arrays.)

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.