{"id":377015,"date":"2026-10-03T14:06:48","date_gmt":"2026-10-03T14:06:48","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/tools-for-elementor-forms\/"},"modified":"2026-10-04T10:34:05","modified_gmt":"2026-10-04T10:34:05","slug":"fw-tools-for-elementor","status":"publish","type":"plugin","link":"https:\/\/kab.wordpress.org\/plugins\/fw-tools-for-elementor\/","author":250087,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.3.2","stable_tag":"0.3.2","tested":"7.1.2","requires":"6.2","requires_php":"8.0","requires_plugins":null,"header_name":"FW Tools for Elementor Forms","header_author":"Olaf Lederer","header_description":"Useful tools and enhancements for Elementor Forms.","assets_banners_color":"e9e7e0","last_updated":"2026-10-04 10:34:05","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"https:\/\/www.olaflederer.com\/","rating":0,"author_block_rating":0,"active_installs":0,"downloads":80,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.3.1":{"tag":"0.3.1","author":"finalwebsites","date":"2026-10-03 18:36:05","revision":3726620},"0.3.2":{"tag":"0.3.2","author":"finalwebsites","date":"2026-10-04 10:34:05","revision":3727310}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3726343,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3726343,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":{"banner-1544x500.jpg":{"filename":"banner-1544x500.jpg","revision":3727310,"resolution":"1544x500","location":"assets","locale":"","width":1543,"height":500},"banner-772x250.jpg":{"filename":"banner-772x250.jpg","revision":3727310,"resolution":"772x250","location":"assets","locale":"","width":772,"height":250}},"assets_blueprints":{},"all_blocks":[],"tagged_versions":["0.3.1","0.3.2"],"block_files":[],"assets_screenshots":{"Screenshot-2.jpg":{"filename":"Screenshot-2.jpg","revision":3726343,"resolution":"2","location":"assets","locale":"","width":1588,"height":1348},"Screenshot-3.jpg":{"filename":"Screenshot-3.jpg","revision":3726343,"resolution":"3","location":"assets","locale":"","width":1602,"height":878},"Screenshot-4.jpg":{"filename":"Screenshot-4.jpg","revision":3726343,"resolution":"4","location":"assets","locale":"","width":1386,"height":784},"Screenshot-5.jpg":{"filename":"Screenshot-5.jpg","revision":3726343,"resolution":"5","location":"assets","locale":"","width":1570,"height":714},"Screenshot-6.jpg":{"filename":"Screenshot-6.jpg","revision":3726343,"resolution":"6","location":"assets","locale":"","width":1238,"height":772}},"screenshots":{"1":"Plugin anti spam settings.","2":"Spam log entries.","3":"Plugin information and REST API test.","4":"Elementor forms setting for confirmation screen.","5":"Example confirmation screen."}},"plugin_section":[],"plugin_tags":[2656,601,232610,2419],"plugin_category":[42,54],"plugin_contributors":[86458],"plugin_business_model":[],"class_list":["post-377015","plugin","type-plugin","status-publish","hentry","plugin_tags-anti-spam","plugin_tags-forms","plugin_tags-rate-limiting","plugin_tags-spam-protection","plugin_category-contact-forms","plugin_category-security-and-spam-protection","plugin_contributors-finalwebsites","plugin_committers-finalwebsites"],"banners":{"banner":"https:\/\/ps.w.org\/fw-tools-for-elementor\/assets\/banner-772x250.jpg?rev=3727310","banner_2x":"https:\/\/ps.w.org\/fw-tools-for-elementor\/assets\/banner-1544x500.jpg?rev=3727310","banner_rtl":false,"banner_2x_rtl":false},"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/fw-tools-for-elementor\/assets\/icon-128x128.png?rev=3726343","icon_2x":"https:\/\/ps.w.org\/fw-tools-for-elementor\/assets\/icon-256x256.png?rev=3726343","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/fw-tools-for-elementor\/assets\/Screenshot-2.jpg?rev=3726343","caption":"Spam log entries."},{"src":"https:\/\/ps.w.org\/fw-tools-for-elementor\/assets\/Screenshot-3.jpg?rev=3726343","caption":"Plugin information and REST API test."},{"src":"https:\/\/ps.w.org\/fw-tools-for-elementor\/assets\/Screenshot-4.jpg?rev=3726343","caption":"Elementor forms setting for confirmation screen."},{"src":"https:\/\/ps.w.org\/fw-tools-for-elementor\/assets\/Screenshot-5.jpg?rev=3726343","caption":"Example confirmation screen."},{"src":"https:\/\/ps.w.org\/fw-tools-for-elementor\/assets\/Screenshot-6.jpg?rev=3726343","caption":""}],"raw_content":"<!--section=description-->\n<p>Keep building your forms in Elementor and manage their protection from one settings page. The plugin checks submissions in the background without asking visitors to solve a CAPTCHA. You can enable or disable individual checks to suit your site.<\/p>\n\n<p>When a submission is rejected, the spam log helps you understand why. Use it to investigate repeated attempts or troubleshoot problems reported by visitors.<\/p>\n\n<p>The optional confirmation step serves two purposes: visitors can review their details before sending, and the additional interaction creates another hurdle for automated submissions. The form's configured actions, such as sending an email, run only after confirmation. You choose which forms use this step.<\/p>\n\n<p>The plugin requires Elementor and Elementor Pro with the Form widget. It is not a standalone form builder.<\/p>\n\n<h4>Features<\/h4>\n\n<ul>\n<li>Browser verification without an additional CAPTCHA challenge.<\/li>\n<li>Checks for missing page information, missing or invalid tokens, and submissions made too quickly.<\/li>\n<li>Honeypot and JavaScript submit controls.<\/li>\n<li>Temporary email field names when browser verification is active.<\/li>\n<li>Settings to enable or disable individual protection checks.<\/li>\n<li>IP and email rate limiting after repeated suspicious submissions.<\/li>\n<li>Optional integration with WP Armour for spam logging and rate limiting.<\/li>\n<li>An optional confirmation step with a configurable title for each form.<\/li>\n<li>A local spam log with recent entries in the WordPress admin and a downloadable JSON Lines file.<\/li>\n<li>Optional country detection using Country.is.<\/li>\n<li>An option to remove plugin settings and stored data when deleting the plugin.<\/li>\n<\/ul>\n\n<h4>Spam log<\/h4>\n\n<p>Logging is enabled by default and can be switched off independently of rate limiting. Disabling logging does not delete existing entries.<\/p>\n\n<p>Entries can contain the submission time, form name, name, email address, IP address, country code, a message excerpt, and the rejection reason. The message excerpt is limited to 125 characters, with whitespace and line breaks combined for easier reading.<\/p>\n\n<p>The log keeps the latest 500 entries by default. Older entries are removed when the limit is exceeded; entries do not expire based on their age. Developers can change the maximum number of entries with the <code>fw_tfe_spam_log_limit<\/code> filter.<\/p>\n\n<p>The log is stored as a JSON Lines file in the <code>fw-tfe-logs<\/code> directory inside the WordPress uploads directory. Spam log entries are not stored in the WordPress database.<\/p>\n\n<h4>IP and email rate limiting<\/h4>\n\n<p>Rate limiting can be enabled or disabled in the plugin settings. Save your chosen setting before using it. When enabled, it uses a separate table in the existing WordPress database.<\/p>\n\n<p>The table stores separate counters for IP addresses and hashes of normalized email addresses, together with the start of each counting period and the end of any block. Email addresses are not stored as plain text in this table. Names and messages are not stored in it.<\/p>\n\n<p>Three suspicious attempts from the same IP address, or five using the same email address, within five minutes trigger a block lasting one hour. Further attempts during that block do not extend it. Ordinary field validation errors and expired verification tokens do not count towards the limit.<\/p>\n\n<p>Expired records are removed in batches during subsequent form requests. Cleanup does not rely on WP-Cron. Disabling rate limiting stops enforcement but leaves the table in place.<\/p>\n\n<h4>Confirmation before sending<\/h4>\n\n<p>Enable \"Require confirmation before sending\" in an Elementor form's options to let visitors review their details before the configured form actions run. You can customize the confirmation title for each form. This feature is off by default.<\/p>\n\n<p>This is an on-page review step, not email address verification. Forms with upload fields skip this step and continue through the normal Elementor submission flow.<\/p>\n\n<p>Pending submissions are stored temporarily in a separate database table, including form field data, form and page identifiers, and form metadata. A confirmation is valid for 15 minutes and can be used only once. Confirmed records remain stored until cleanup; cancelling an unclaimed confirmation deletes its pending record.<\/p>\n\n<p>Expired records are removed by an hourly WP-Cron task. Actual deletion can occur later, depending on when WordPress runs scheduled tasks. Temporary confirmation storage is independent of spam logging.<\/p>\n\n<h4>WP Armour integration<\/h4>\n\n<p>When WP Armour is active and the integration is enabled, its Elementor form rejections can be included in this plugin's spam log and rate limiting. Logging and rate limiting must each be enabled for their respective functions to apply.<\/p>\n\n<p>WP Armour is optional and is not bundled with this plugin. Disabling the integration does not disable WP Armour's own protection.<\/p>\n\n<h3>External services<\/h3>\n\n<h4>Country.is<\/h4>\n\n<p>Country.is is an optional IP geolocation service used to retrieve a country code for a spam log entry. It is disabled by default and is used only after a site administrator selects Country.is in the country detection setting.<\/p>\n\n<p>When logging a rejected submission with a valid IP address, the plugin sends that address in an HTTPS request to <code>https:\/\/api.country.is\/{ip}<\/code>. Submitted names, email addresses, and message contents are not included in this lookup. As with other server-side HTTP requests, the service also receives the connection from your web server.<\/p>\n\n<p>Country.is does not require an API key. According to the Country.is website, the API is free for commercial use, its data comes from MaxMind GeoLite2 and Cloudflare geolocation, and API requests are not logged by the service.<\/p>\n\n<p>Country.is does not currently publish separate Terms of Service or Privacy Policy pages. Therefore, no direct links to such pages can be provided. The service information, usage conditions and privacy-related information published by Country.is are available on its website:<\/p>\n\n<p><a href=\"https:\/\/country.is\/\">Country.is<\/a><\/p>\n\n<h3>Privacy and data storage<\/h3>\n\n<p>When logging is enabled, the plugin stores the personal information listed in the Spam log section on your server. When rate limiting is enabled, IP addresses, hashes of normalized email addresses, and temporary rate limit state are stored in a dedicated database table.<\/p>\n\n<p>When the confirmation step is used, submitted form fields and metadata are stored temporarily in a separate database table, along with a hash of the confirmation token, an expiry time, and whether the confirmation has been used. This storage is not limited to the short message excerpt kept in the spam log.<\/p>\n\n<p>Only optional country detection sends a visitor's IP address to Country.is. Include your use of these features in your site's privacy information as appropriate.<\/p>\n\n<p>The spam log has an entry limit rather than an age limit. Rate limit records become eligible for deletion after their counting period and any block have expired; physical deletion takes place during later form requests. Confirmation records expire after 15 minutes and are removed by the scheduled cleanup described above.<\/p>\n\n<!--section=installation-->\n<p>This plugin requires both Elementor and Elementor Pro to be installed and active.<\/p>\n\n<ol>\n<li>Upload the plugin directory to <code>\/wp-content\/plugins\/<\/code> and activate FW Tools for Elementor Forms in WordPress.<\/li>\n<li>Open Tools &gt; Elementor Forms and select the Settings tab.<\/li>\n<li>Review the protection settings and save your choices for spam logging, IP and email rate limiting, and country detection.<\/li>\n<li>Check browser verification on the Information tab and use \"Test endpoint\" or \"Test again\" if needed.<\/li>\n<li>Optionally enable \"Require confirmation before sending\" in the options of individual Elementor forms.<\/li>\n<li>Submit a test through your Elementor form and check that normal submissions still work.<\/li>\n<\/ol>\n\n<p>Country detection is optional and disabled by default. The confirmation step is disabled until enabled for an individual form.<\/p>\n\n<!--section=faq-->\n<dl>\n<dt id=\"does%20this%20work%20with%20the%20free%20version%20of%20elementor%3F\"><h3>Does this work with the free version of Elementor?<\/h3><\/dt>\n<dd><p>The plugin works with the Form widget provided by Elementor Pro. Elementor Pro is required in addition to Elementor.<\/p><\/dd>\n<dt id=\"do%20i%20need%20to%20change%20my%20form%20fields%3F\"><h3>Do I need to change my form fields?<\/h3><\/dt>\n<dd><p>For the spam log to capture a name, set that field's ID to <code>name<\/code> in Elementor. This refers to the field ID, not its visible label.<\/p>\n\n<p>The plugin uses the first populated email field and the first populated textarea field for the logged email address and message. Their field IDs can be different. Forms without those fields can still be used; the corresponding log values remain empty.<\/p><\/dd>\n<dt id=\"does%20the%20plugin%20log%20every%20form%20submission%3F\"><h3>Does the plugin log every form submission?<\/h3><\/dt>\n<dd><p>No. When enabled, the spam log records rejections from this plugin's page information, submit control, honeypot, browser verification, and temporary email field checks. It can also record WP Armour rejections when the integration is enabled.<\/p>\n\n<p>Successful submissions are not added to the spam log. Requests rejected because an IP address or email address is already blocked do not create additional entries. The optional confirmation step stores pending form data separately, even when spam logging is disabled.<\/p><\/dd>\n<dt id=\"what%20happens%20if%20someone%20leaves%20a%20form%20open%20for%20a%20long%20time%3F\"><h3>What happens if someone leaves a form open for a long time?<\/h3><\/dt>\n<dd><p>Browser verification tokens expire after two hours. An expired token causes the submission to be rejected with a form error. These rejections can be logged but do not count towards a rate limit block.<\/p>\n\n<p>The optional confirmation step has a separate 15-minute validity period.<\/p><\/dd>\n<dt id=\"does%20rate%20limiting%20block%20every%20visitor%20using%20that%20ip%20address%3F\"><h3>Does rate limiting block every visitor using that IP address?<\/h3><\/dt>\n<dd><p>Yes. IP limits apply across forms on the site, so visitors sharing a connection can share a block. Email limits also apply across forms, using the submitted email address independently of the IP address. A block on either identifier prevents submission.<\/p><\/dd>\n<dt id=\"can%20i%20use%20rate%20limiting%20without%20the%20spam%20log%3F\"><h3>Can I use rate limiting without the spam log?<\/h3><\/dt>\n<dd><p>Yes. Rate limiting has its own database table and works independently of spam logging.<\/p><\/dd>\n<dt id=\"does%20country%20detection%20block%20countries%3F\"><h3>Does country detection block countries?<\/h3><\/dt>\n<dd><p>No. It adds a country code to spam log entries to help you analyse rejected submissions. Country-based blocking is not included.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20the%20token%20endpoint%20is%20unavailable%3F\"><h3>What happens when the token endpoint is unavailable?<\/h3><\/dt>\n<dd><p>Token verification is enforced only when the plugin's REST endpoint check reports that the endpoint is available. Other enabled checks, including the missing page information check, honeypot, submit control, and rate limiting, can still apply. Temporary email field names depend on browser verification.<\/p><\/dd>\n<dt id=\"what%20happens%20when%20i%20delete%20the%20plugin%3F\"><h3>What happens when I delete the plugin?<\/h3><\/dt>\n<dd><p>By default, stored settings and data are retained. Enable the option to delete all plugin settings and the spam log before deleting the plugin if you want uninstall to remove them. This also removes the rate limit and confirmation tables and their related settings.<\/p>\n\n<p>Deactivating the plugin or switching off a feature does not uninstall its stored data. Deactivation stops the scheduled confirmation cleanup.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.3.2<\/h4>\n\n<ul>\n<li>Added: Optional detection of random-looking names in the field with ID \"name\". Blocked attempts are logged as \"random_name\" and count toward rate limiting.<\/li>\n<li>Fixed: WP Armour compatibility with the confirmation step. Initial submissions remain protected by WP Armour; confirmed submissions skip its repeated check after successful single-use token validation.<\/li>\n<\/ul>\n\n<h4>0.3.1<\/h4>\n\n<ul>\n<li>Added Dutch translations<\/li>\n<li>Added assetts (icon and banner) <\/li>\n<\/ul>\n\n<h4>0.3.0<\/h4>\n\n<ul>\n<li>Added an optional confirmation step so visitors can review their details before sending.<\/li>\n<li>Added honeypot and additional browser-side form checks.<\/li>\n<li>Added temporary email field names for browser verification.<\/li>\n<li>Extended rate limiting to track suspicious submissions by both IP address and email address.<\/li>\n<li>Added integration with WP Armour to include its Elementor form rejections in spam logging and rate limiting.<\/li>\n<li>Added settings to enable or disable individual protection checks.<\/li>\n<li>Extended spam logging with additional rejection reasons and the form name.<\/li>\n<li>Updated the plugin name to FW Tools for Elementor Forms.<\/li>\n<li>Updated documentation for external services, temporary data storage, and data removal.<\/li>\n<\/ul>\n\n<h4>0.2.0<\/h4>\n\n<ul>\n<li>Browser verification for Elementor Pro forms.<\/li>\n<li>Local spam logging with admin display and download.<\/li>\n<li>Optional Country.is country detection.<\/li>\n<li>Optional IP rate limiting and cleanup of expired records.<\/li>\n<li>Settings for logging, country detection, rate limiting, and uninstall data removal.<\/li>\n<\/ul>","raw_excerpt":"Spam protection, IP and email rate limiting, local spam logs, and an optional review-before-send step for Elementor Pro forms.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/377015","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=377015"}],"author":[{"embeddable":true,"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/finalwebsites"}],"wp:attachment":[{"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=377015"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=377015"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=377015"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=377015"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=377015"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/kab.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=377015"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}