Contact Form 7 is one of the best WordPress plugins when it comes at creating contact forms. The reasons behind its success have deep roots in its technical specs: Contact Form 7 is an essential plugin in its aesthetic, yet very powerfull for those who understand code and the underlying logics. This makes CF7 flexible, lightweight and powerful, being able to gain new functionalities with tailor made addons, still keeping the bar high in terms of security and performance.
It’s possible to do a lot of things with Contact Form 7: addons allow for almost unlimited customization, exactly as plugins do for WordPress itself. You can expand Contact Form 7 to integrate a PayPal button, or a complex form with conditional fields; or ensure better security and spam filtering with two different captchas, now wrapped in their own addons, such as Quiz Captcha and Really Simple Captcha.
Contact Form 7: integrated captchas and cached pages
This is quite a hidden issue, however one of the biggest problems in Contact Form 7 comes from its historic captchas: Quiz and Really Simple Captcha, when they’re paired with a caching plugin (f.eg W3 Total Cache, WP Super Cache or others).
When a caching plugin is in use, it “just” saves a static copy of our website pages within a specific folder: this copy will be provided to the users, in place of the dynamically generated page as it should usually happen in modern websites. This “trick” provides better performances and user experience, reducing resource usage. When the page is updated with new content, the static copy (and other related pages) gets updated to, providing the newly created fresh content to the users.
Sometimes, this can be an issue for plugins such as Contact Form 7: the native captchas need to dynamically generate some hidden fields in the forms, or update the captcha image, in order to be able to validate the answer, which must be different from user to user: that’s captcha 101.
Contact Form 7: the refill function
Since cached pages always show static content, Contact Form 7 captchas needed a workaround. This is how it’s implemented: during page load, a script detects if the page is cached. If yes, an AJAX request is sent to the server, which answers with a fresh new quiz, or a brand new distorted image. This update is managed by the refill function.
Here’s what: the problem is that it takes an enormous amount of time, from 500 to 1000ms or more, according to your server performance and network status.
The time loss is huge. Think of it as more than a half the time the page needs to fully load. So, if it’s true that this function is fundamental in order to make the captchas work, it’s even true that it’s a real issue. A caching plugin is used to make our website faster, not slower: we need to fix it somehow.
Fixing the refill issue on Contact Form 7
Now, if we know this function is fundamental when it comes to the provided captchas, we cannot waste all that time for it. How can we fix it?
Many similar posts about it suggest a pretty radical solution: disable the captchas and move to other anti spam systems such as Honeypot for Contact Form 7.
Honeypot for Contact Form 7 makes traps for bots: fake input fields are placed on each form, but hidden to humans. When bots try to fill those fields, the form cannot be sent. Smart, uh?
Yes, it’s a smart approach. However, some bots are smarter than others, so we may want to look for a more reliable solution, right?
Recaptcha: refill request asks, the server aswers with… nothing!
After few hours playing with the settings for possible solutions, we noticed a really important behaviour. When Google Recaptcha is in use on its own Contact Form 7 implementation, the refill request still fires, however… it gets an empty response from the server!
This means that the Contact Form 7 Recaptcha implementation does not make any practical use of the refill function, even if it is still sent. Wow! This hypotesis can be easily confirmed by verifying how the refill function is being used on the plugin’s source code:
- scripts.js: Contact Form 7 scripts file calls the refill function when the global variable wpcf7.cached is equal to 1 (or true)
- the refillCaptcha variable on line 432 is used to handle Really Simple Captcha’s refill
- the refillQuiz variable on line 440 is used to handle Quiz Captcha’s refill
- Looking to the PHP code executing the AJAX request, there are references for these two kind of captcha only: no Google Recaptcha in sight
So, all we have to do is: set wpcf7.cached to 0 when Google Recaptcha is in use. Simple as pouring a glass of water.
How to disable the refill request when Recaptcha is in use
Just like all the best WordPress plugins, Contact Form 7 too comes with an excellent system of filters and actions, which are awesome when it comes at customizing its behaviour. Moreover, we can use WPCF7 built-in functions and methods to check its settings, such as detecting internal service status: for example, we can check if Google Recaptcha is in use by recalling the single instance of the WPCF7_RECAPTCHA class. Come tutti i migliori plugin per WordPress, anche Contact Form 7 utilizza un eccellente sistema di filtri ed azioni per permetterci di modificare il suo comportamento.
So, this is what our code will look like:
With this small snippet, we tie our function wpcf7_recaptcha_no_refill() to wp_enqueue_scripts, a pretty basic and very important WordPress Core action which is usually used to handle script registration. Now, this is what our wpcf7_recaptcha_no_refill function does:
- It saves the current instance of WPCF7_RECAPTCHA in the $service variable
- If the is_active() class method (called with $service->is_active()) evaluates to false, then it just does nothing, because that means Recaptcha is not active
That’s it! Now we just won’t have any more annoying and time consuming useless AJAX requests.