questions

How could I write a hook that restricts one IP address for submitting applications from Contact Form 7?

Rate this post

I have a form for subscription.

And I want to limit the number of submits by IP, for example, 3 times a day?

How can I do it with hooks?

 

✔️Solution:

Use the WordPress do_shortcode_tag filter introduced in v4.7, which get fired when a shortcode is rendered. You can then replace the rendered CF7 form with a notification for users who have reached their submitted limit

add_filter('do_shortcode_tag', 'restrict_my_form',10,3);
function restrict_my_form($output, $tag, $attrs){
  //check if this is your form being rendered.
  if($tag=='contact-form-7' and $attrs['id'] == 1){
    //get the IP address of the submission as $ip_address
    $cannot_submit = get_transient('form_submission_from_'.$ip_address);
    if($cannot_submit !== false){
      $cannot_submit = explode('|',$cannot_submit);
      if($cannot_submit[0] > 2){ //already submitted 3 times.
        $cannot_submit = true;
      }else{ //can still submit.
        $cannot_submit = false;
      }
    }//else this is the first submit or transient expired.

    if($cannot_submit){ 
      //replace the html for with your notification.
      $output ='<p>You have reached the limit of submissions</p>';
    }
  }
  return $output;
}

To verify the IP of the user, the question has already been answered here.

You will also need to track users’ submissions per IP, I suggest you store these as transients for 24 hours, this way they will automatically disappear after a day. Something along these lines (I haven’t tested this code, so let me know if you’re not getting the expected results.)

add_action('wpcf7_mail_sent', function($form){
  //get the IP address of the submission as $ip_address
  $time = current_time('timestamp');
  $expiry = DAY_IN_SECONDS; //24 hours.
  $value = 1;
  $last_value = get_transient('form_submission_from_'.$ip_address);
  if($last_value !== false){
    $last_value = explode('|',$last_value);
    $expiry = DAY_IN_SECONDS - ($time - $last_value[1]); //remaining time since first submission.
    $time = $last_value[1]; //keep time of first submission.
    $value = ($last_value[0]+1);
    delete_transient('form_submission_from_'.$ip_address);
  }
  $value = "$value|$time";
  set_transient('form_submission_from_'.$ip_address, $value, $expiry);
});

Leave a Reply

Your email address will not be published.

Back to top button