Stopping Jerks in Ninja Forms

I don’t have a spam problem, I have a jerky people problem. I have people who, no matter how many times I explain I cannot help them, or I don’t want to talk to them, will continue to email.

Right now, I have some absolute weirdo in Europe who emails me every day via a contact form. I don’t know what the heck he’s thinking, but I do not need advice about how to live my life nor can I help him talk to a celebrity. The problem though is I can’t delete the form. I can (and did) set his email to auto-bin via my mail server, but he still fills the form in and I am just tired of cleaning this up.

This site happens to use Ninja Forms, and really what I want to do is auto-cycle his emails to the bin so he can rant all he wants and never knows I don’t see a thing.

(Note: This is not the same person as my serial harasser.)

Warning: Their Documentation is Rough

The biggest headache to all this is the fact that Ninja Forms’ documentation kinda sucks. For example, you cannot search their ‘codex‘! That’s just basic level for a documentation service, and on top of that if you try googling, it wants to send you to the non-developer pages.

Now to their credit they know this:

Admin note: we have not been able to give this site the attention it needs or deserves for a while. Most of the Codex documentation is still applicable, but please be aware that you will find some outdated material here that will need to be adapted for Ninja Forms in its current, more modern, state. 

But that doesn’t make it really any better for me today, and it’s been like that for a while.

Which means thinking “I can search for how to auto-flag a submission as spam/trash!” is impossible. It doesn’t work, it doesn’t exist in current NF format, and it’s a pain to the point that I seriously considered dumping the whole plugin over this!

Folks. I know documentation is incredibly hard, but if you want people to make plugins to extend yours, and thus help make you even more popular, hire someone to do this. It’s only gonna get harder as time goes on.

The Initial Code

The first step is, of course, can I even do this, and of course I can:

<?php
/**
 * Prevent anyone from my blocklist from spamming me.
 */

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit;


class FLF_NinjaForms {

	/**
	 * List of disallowed emails
	 *
	 * We omit anything that isn't an email address or has an @ in the string.
	 *
	 * @return array the list
	 */
	public static function list() {
		$disallowed_emails = array();
		$disallowed_array  = explode( "\n", get_option( 'disallowed_keys' ) );

		// Make a list of spammer emails and domains.
		foreach ( $disallowed_array as $spammer ) {
			if ( is_email( $spammer ) || ( strpos( $spammer, '@' ) !== false ) ) {
				// Anything with an @-symbol is probably an email, so let's trust it.
				$disallowed_emails[] = trim( $spammer );
			}
		}

		return $disallowed_emails;
	}

	/**
	 * On load.
	 */
	public function __construct() {
		add_filter( 'ninja_forms_submit_data', array( $this, 'comment_blocklist' ) );
	}

	/**
	 * Ninja Forms: Server side email protection using WordPress comment blocklist
	 * https://developer.ninjaforms.com/codex/custom-server-side-validation
	 *
	 * @param array $form_data Form data array.
	 * @return array $form_data email checked form data array.
	 */
	public function comment_blocklist( $form_data ) {
		$disallowed = self::list();

		foreach ( $form_data['fields'] as $field ) {
			// If this is email, we will do some playing.
			if ( 'email' === $field['key'] ) {
				$email_address = sanitize_email( strtolower( $field['value'] ) );

				// Break apart email into parts
				$emailparts = explode( '@', $email_address );
				$username   = $emailparts[0];       // i.e. foobar
				$domain     = '@' . $emailparts[1]; // i.e. @example.com

				// Remove all periods (i.e. foo.bar > foobar )
				$clean_username = str_replace( '.', '', $username );

				// Remove everything AFTER a + sign (i.e. foobar+spamavoid > foobar )
				$clean_username = ( false !== strpos( $clean_username, '+' ) ) ? strstr( $clean_username, '+', true ) : $clean_username;

				// rebuild email now that it's clean.
				$email = $clean_username . '@' . $emailparts[1];

				// If the email OR the domain is an exact match in the array, then it's a spammer
				if ( in_array( $email, $disallowed, true ) || in_array( $domain, $disallowed, true ) ) {
					$form_data['errors']['fields'][ $field['id'] ] = 'Error: Invalid data.';
				}
			}
		}
		return $form_data;
	}

}

new FLF_NinjaForms();

This code takes the email, strips out any periods (since Google allows you to put those in anywhere in your username) and then also removes anything after a + sign (since… Google lets you add in random whatever after a + sign) and builds a sanitized email. Then it checks that email on my block list. It also checks if I banned the domain.

The Problem

The only problem?

				// If the email OR the domain is an exact match in the array, then it's a spammer
				if ( in_array( $email, $disallowed, true ) || in_array( $domain, $disallowed, true ) ) {
					$form_data['errors']['fields'][ $field['id'] ] = 'Error: Invalid data.';
				}

That tells them “Error: Invalid Data” for the email. Which will suggest to them to try something else.

I don’t want that!

So I thought what if I changed that error to this:

$form_data['fields']['is_spam'] = true;

Which sets a new field for me! Is spam.

The only problem? Well I thought I could use that with ninja_forms_after_submission to then say “Submission is in but we are going to treat it as trash and not email it.” Ever tried to look up ‘don’t email Ninja Forms’? Or any form? Yeah, all you get it help if Ninja Forms isn’t sending email.

Then I thought I could set it as actual spam, but Ninja Forms has the most useless advice:

If you’ve used all the methods above and you still receive spam submissions, maybe it’s time to change your hosting provider. Ideally, they can help you minimize spam and provide you a web application firewall to keep those spambots off your website.

My host isn’t the issue. This jerk is. And both Jetpack and Gravity Forms have an _is_spam filter/action you can hook. I find it very odd that native mark-as-spam isn’t a think in Ninja Forms, and honestly it’s putting more fuel to the ‘change tools’ fire. This is some basic stuff, ain’t it? If you can hook into Aksimet and have it catch spam, why can’t you mark as spam and send that data back to make everyone’s life better?

Is this the end?

Well. For now it is. For next it’s not. I think the real answer will be to create an action like they have for Akismet, and in there rebuild my spam tool.

Maybe as a plugin for all.

But for right now, I actually turned off the forms entirely. No more contact form. The only person really using it was that yahoo, and instead I have the email address up there for now. Likely I’ll go back to Jetpack for a while, or maybe write a whole, complex, add on plugin. Later.

%d