OK the gist should be good.
Initially I thought that the
if ( $error == false ) {
would be the place to put the check, but there is an issue with non bot spam in terms of false negatives, in that case you want the spam to be logged in the submissions post, marked as spam, but not send an email.
So the filters and conditions have to be further down.
In terms of how filters work, filter change a variable, the first in the list, but also pass down other data as variables ( as many as you want ) so the filter can make logic choices.
so $post_status = apply_filters( 'vscf_pre_database_save', 'pending', $form_data );
if there is nothing adding the filter the first argument is returned, so in that case $post_status is pending
exactly as your original code intends.
However a filter can receive multiple arguments and so will receive form data, and hence an anti-spam filter can analyse the $form_data and return a post status of pending
or spam
if it THINKs it is spam but not 100% sure ( e.g. spam probability > 70% or false
if it is certain i.e. bot detected.
So an add filter would look like
add_filter('vscf_pre_database_save', function($post_status, $form_data) {
if ( spam_analysis($form_data) == 100 ) {
$post_status = false;
} else if ( spam_analysis($form_data) > 70 ) {
$post_status = 'spam';
}
return $post_status;
}, 10, 2 );
( there is something else needed so the ‘spam’ post_type items show as a link in the list table of submissions, but that is trivial )
The second if / filter just before email sending simply needs to check if the post_type was pending – as that means – send the email, as your original code would. ( I just placed the filter there to make your code more customisable as I noticed the last line of this review https://www.ads-software.com/support/topic/its-great-but-some-things-are-missing/ and that filter would enable turning off email sending )
I hope that explains why the filter and if’s need to be lower down the code.