=== Webcraft Forms ===
Contributors: kleinsascha
Tags: contact form, form builder, forms, gdpr, dsgvo
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 8.1
Stable tag: 1.25.2
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

A form builder that never talks to anyone else's server. Local spam protection, no Google reCAPTCHA, no cloud storage, no vendor account.

== Description ==

Most form plugins ask you to accept a third party: a captcha loaded from Google, entries kept in the vendor's cloud, an account somewhere. Webcraft Forms is built the other way round.

**What makes it different**

* **Spam protection that stays on your server.** ALTCHA proof-of-work runs entirely on your own site – no account, no external service, no CDN, no data transfer. It is the default. Google reCAPTCHA is deliberately not supported at all.
* **No outbound request, ever, unless you ask for one.** No tracking, no phone-home, no usage statistics. The only optional exception is Friendly Captcha, and only if you switch it on with your own credentials.
* **Nothing is stored anywhere but your database.** Submissions are sent by e-mail and processed on your own server. There is no vendor cloud in the free version and none in the paid add-on either.
* **Column layout per device.** Set each field's width separately for desktop, tablet and phone, with inheritance – the way a page builder works. The canvas narrows to the simulated device so you see the real result.
* **Conditional display included, not sold separately.** Show or hide any field based on other fields' values, evaluated in the browser and verified again on the server.

This matters for sites under the GDPR, where every external service in a contact form is one more data processor to document. It is written for small and medium businesses that need a form which a data protection officer can sign off without a second thought.

The builder has its own admin interface and a live canvas: what you see while building is exactly what visitors see on the front end. It works independently of the block editor.

**Building forms**

* Live canvas with inline editing, drag and drop and row-based layout
* Field widths per device (desktop, tablet, phone) with inheritance, like a page builder
* Field types: text and multiline text, e-mail, phone, website, number, date, time, dropdown, radio buttons, checkbox, multiple choice, consent checkbox, multi-part name, heading with optional divider, free text, hidden field with a dynamic value
* Conditional display per field: show or hide a field based on the values of other fields, evaluated on the client and verified again on the server
* Duplicate forms, export and import them as JSON, start from one of three templates

**Sending and confirmation**

* Multiple recipients plus CC and BCC
* Reply-To set to the address the visitor entered
* Confirmation as an on-page message or as a redirect to any URL
* Auto-responder with its own subject and body, placeholder for the submitted data
* Internal label added to the notification only, never to the auto-responder

**Spam protection**

* Honeypot, always active
* ALTCHA: local proof-of-work, the default for new forms
* Friendly Captcha as an optional alternative. You bring your own site key and API key; the plugin only provides the connection fields and never proxies the service. Its browser SDK is bundled with the plugin, so nothing is fetched from a CDN. See "External services" below.

**Output**

* Shortcode `[webcraft_form id="123"]`
* Elementor widget, registered only when Elementor is active

**Privacy**

The free plugin makes no outbound request unless you explicitly choose Friendly Captcha. In that case the browser talks to Friendly Captcha to fetch and solve the puzzle, and your server verifies the submitted solution against the Friendly Captcha API using your own credentials. The SDK itself is served from your own site. With ALTCHA or without a captcha, the plugin contacts no external server at all.

**Premium add-on**

The separate add-on Webcraft Forms Premium adds file uploads, multi-step forms with a progress bar, tile choices with an image or icon per option, calculated fields, a signature pad, save and resume in the browser, conditional notifications and confirmations, entry storage with CSV export and a data retention period. The free plugin contains no locked premium code, only extension points.

== Installation ==

1. Upload the plugin folder to `/wp-content/plugins/` or install it through Plugins → Add New.
2. Activate the plugin.
3. Open "Webcraft Forms" in the admin menu and create your first form, empty or from a template.
4. Place the shortcode `[webcraft_form id="123"]` on any page, or use the Elementor widget.

== Frequently Asked Questions ==

= Does the plugin send data to external servers? =

No. Forms are processed on your own server and e-mails are sent through WordPress. The only optional exception is Friendly Captcha, which you have to select and configure yourself with your own account.

= Do I need an account for spam protection? =

No. ALTCHA runs entirely on your own site as a local proof-of-work challenge and is preselected for new forms.

= Where are submissions stored? =

The free plugin sends submissions by e-mail and does not store them. Storing entries in the database, exporting them as CSV and deleting them after a retention period are part of the Premium add-on.

= Does it work without Elementor or the block editor? =

Yes. The builder is standalone and the shortcode works in any editor and any theme.

= Can I translate the plugin? =

Yes. All strings are translatable and a `webcraft-forms.pot` template is included in the `/languages` folder. Translations are distributed through translate.wordpress.org and installed by WordPress automatically.

== External services ==

This plugin can use one external service. It is optional, switched off by default and only ever contacted when you select it for a form and enter your own credentials.

**Friendly Captcha** (Friendly Captcha GmbH, Am Anger 3-5, 82237 Woerthsee, Germany)

* **What it is and what it is used for.** Friendly Captcha is a proof-of-work anti-bot service. It is one of the spam protection methods offered per form, as an alternative to the built-in local method (ALTCHA) which needs no service at all. It is used only if you select "Friendly Captcha" in the form settings and enter your own site key and API key from your own Friendly Captcha account.
* **What data is sent and when.** Two moments only. First, when a visitor loads a page carrying such a form, the visitor's browser requests a puzzle from Friendly Captcha and sends the connection, environment and interaction data that Friendly Captcha needs to assess it, including the IP address. Second, when the form is submitted, your server sends the solution together with your site key and API key to `https://global.frcapi.com/api/v2/captcha/siteverify` (or `https://eu.frcapi.com/api/v2/captcha/siteverify` if you switch on the EU endpoint) and receives back whether the puzzle was solved correctly. No form content is transmitted at any point.
* **Where the code comes from.** The browser SDK is bundled with this plugin (`assets/vendor/friendlycaptcha`, version 1.0.1, Mozilla Public License 2.0) and served from your own site. Nothing is loaded from a CDN.
* **Terms and privacy.** Terms of Use: https://friendlycaptcha.com/legal/terms/ - Privacy Policy for End Users: https://friendlycaptcha.com/legal/privacy-end-users/ - Legal centre: https://friendlycaptcha.com/legal/

If you do not select Friendly Captcha, this plugin makes no request to any external service.

== Screenshots ==

1. The builder with the live canvas and the field panel
2. Field options with conditional display
3. Form settings: notification, confirmation, auto-responder, design and spam protection
4. The form on the front end

== Changelog ==

= 1.25.2 =
* The links to the plugin page follow its new address
* No change in behaviour

= 1.25.1 =
* Plugin Check pass on 1.25.0: the four remaining warnings resolved. Two concerned the `meta_key` column written by the one-off migration, two concerned unprefixed variables in `uninstall.php`
* No change in behaviour

= 1.25.0 =
* All identifiers now use the prefix `wcforms_` instead of `wcf_`, as required for the WordPress.org directory. This affects the post type of the forms, the meta keys, the option, the script handles and every hook. Existing forms are migrated automatically on the first request after the update
* Extensions have to be updated as well; Webcraft Forms Premium 1.11.0 or later is required
* The Friendly Captcha SDK is bundled with the plugin (version 1.0.1, MPL-2.0) instead of being loaded from a CDN, and is pinned to a fixed version
* New readme section "External services" documenting the Friendly Captcha connection, the data sent and the links to its terms and privacy policy
* Builder data is handed over through `wp_add_inline_script()` instead of an inline script tag
* Extensions no longer receive the raw `$_POST` array through `wcforms_save_settings`, but an unslashed and cleaned copy
* Removed `load_plugin_textdomain()` and the bundled translation files; WordPress loads translations from translate.wordpress.org by itself

= 1.24.1 =
* Forms are now styled correctly inside the Elementor editor preview.
* New hook `wcf_preview_assets` for extensions that ship their own front-end files.

= 1.24.0 =
* Extensions can now provide their own form templates (filters `wcf_template_fields` and `wcf_template_title`).
* Without Premium, the premium templates are shown greyed out below the template buttons.

= 1.23.1 =
* readme.txt: description rewritten to state up front what sets the plugin apart – local spam protection, no external requests, no cloud storage, per-device column layout, conditional display in the free version
* No code change

= 1.23.0 =
* German now ships in both forms of address: `de_DE` uses the informal "du", `de_DE_formal` uses the formal "Sie". WordPress treats these as two separate locales, and until now only one file existed – sites set to "Deutsch (Sie)" fell back to English
* Both variants are complete and include the script translations

= 1.22.0 =
* The premium section of the field palette now shows every field type the add-on provides – file upload, page break, tile choice, calculation and signature – instead of file upload alone
* The note below it lists the current premium feature set; it still described the state of version 1.0
* Description in readme.txt updated accordingly

= 1.21.1 =
* Eight strings in the builder were still hard-coded and stayed German regardless of the site language: the width bar label, the "Required" chip, the drag handle tooltip, the salutation and divider switches, the multiline switch and the name field preview. They are translatable now
* Template now has 262 strings, the German translation covers all of them

= 1.21.0 =
* Source language changed to English. All strings in PHP and JavaScript are now English in the code, which is the WordPress convention and lets translators on translate.wordpress.org work from an English original
* German is now shipped as a translation (`de_DE`), complete for all 256 strings, including the script translations
* About 28 strings in the builder that were previously hard-coded are now translatable as well (conditional display, field toolbar, option editor)
* No change in behaviour or data

= 1.20.2 =
* Translations are now loaded through `load_plugin_textdomain()`, so a language file placed directly in the plugin's `/languages` folder is picked up as well
* No other change

= 1.20.1 =
* Translation template `/languages/webcraft-forms.pot` regenerated (228 strings, previously 205); it now covers the strings added in 1.16.x to 1.20.0
* No code change

= 1.20.0 =
* New extension point `window.WCF_PANEL_EXTRAS`: add-ons can append their own controls to the field options panel of any field type, not just their own
* Entries provide `options(field, api)` and `panelEvent(field, event, api)`; a faulty add-on cannot break the panel
* Builder API gains `getFields()`
* New filter `wcf_computed_values`: add-ons can supply values that only follow from all fields together, such as a calculation; the value is available to notifications, entries and conditions
* No change in behaviour on its own

= 1.19.0 =
* New field type: hidden field with a dynamic value. The value is filled on request from a URL parameter, the page title, the page address or the logged-in user, with an optional fallback
* Useful for campaign and source attribution, especially for one form placed on many pages by shortcode
* The value is always resolved again on the server when the form is submitted and never taken from the submitted form; it is never required and never rendered as a visible control
* The field can be used as the reference of a conditional display like any other field
* New filters `wcf_hidden_sources` and `wcf_hidden_value`

= 1.18.0 =
* Form settings are now a centred dialog with a vertical tab list instead of a narrow side drawer: Sending, Confirmation, Auto-responder, Design, Spam protection
* New filter `wcf_settings_panes` so add-ons can register their own tab; sections still hooked to the older `wcf_settings_panel_sections` are shown in a separate tab
* Narrow screens move the tab list to the top

= 1.17.0 =
* Extension points for conditional notifications and confirmations: add-ons can filter the list of notifications sent for a submission and replace the redirect target and the on-page success message
* New filters `wcf_notifications`, `wcf_success_target` and `wcf_success_text`; a notification may carry its own body text with the `{daten}` placeholder
* No change in behaviour on its own: without an add-on the plugin still sends exactly one notification and shows the configured message

= 1.16.1 =
* Client-side validation now treats any radio or checkbox group as empty until something is checked, including groups rendered by add-ons
* Add-on field defaults are deep-copied so two fields of the same type no longer share one object

= 1.16.0 =
* Fields now carry an `ext` container that add-ons can use for their own data; it is preserved on save even while the add-on is inactive
* Registry gains `panelEvent` so add-ons can handle their own controls in the field options panel
* Condition values offer a dropdown for any field that carries options, including add-on field types

= 1.15.1 =
* Translation template regenerated: 205 strings, including the two new builder strings from 1.15.0

= 1.15.0 =
* Field types from an add-on that is temporarily inactive are now kept on save instead of being turned into text fields
* Such fields are shown locked in the builder, are not rendered on the front end, and are never validated, mailed or stored
* Re-activating the add-on brings them back unchanged

= 1.14.0 =
* Extension points for custom field types: add-ons can register a field type with its own canvas card, preview and option controls
* New filter wcf_field_display_only, new actions wcf_builder_assets and wcf_form_render
* Front-end validation helpers exposed for add-ons, plus a wcf:form-init event per form
* The builder now draws the canvas on DOMContentLoaded so registrations from later scripts are picked up

= 1.13.5 =
* Plugin Check pass: all nine warnings resolved
* Saved settings run through the standard sanitizing functions before the plugin-specific checks
* Removed the manual load_plugin_textdomain() call, discouraged since WordPress 4.6

= 1.13.4 =
* Code pass against the WordPress Coding Standards ahead of the plugin review: no findings left
* The Friendly Captcha SDK is now loaded through the script queue instead of inline script tags
* Form tag output escaped attribute by attribute; the enctype allow list returns a plain value

= 1.13.3 =
* Editing a saved form now highlights "Alle Formulare" in the admin menu instead of "Neues Formular", and the browser tab shows the correct title.

= 1.13.2 =
* Builder and front-end scripts are translatable again, this time through the standard `wp.i18n` API and `wp_set_script_translations()`, so Loco Translate and comparable tools pick them up.
* Fixed the naming collision that emptied the builder canvas in 1.13.0: the translation helper shadowed an existing local variable.

= 1.13.1 =
* Fix: the builder canvas stayed empty after 1.13.0. The translation layer for the builder script has been removed again; the script is back to its proven state.
* The form data handed to the builder is now guarded against invalid JSON encoding.

= 1.13.0 =
* All interface strings are now translatable, `webcraft-forms.pot` added
* Plugin header completed (license, minimum WordPress version, domain path)
* Security pass: button colours, corner radius, site key and API key escaped at output; the `wcf_form_enctype` filter is checked against an allow list
* ALTCHA is preselected as the captcha method for new forms; existing forms are unchanged

= 1.12.0 =
* Notice when a Friendly Captcha check could not be carried out (network error, HTTP error, unexpected response, missing keys), with time and reason in the admin area
* Submissions are still accepted in that case; the notice disappears once the service answers again

= 1.11.0 - 1.11.3 =
* Duplicate a form, export and import forms as JSON, three form templates
* Delete a form, with confirmation

= 1.10.0 - 1.10.1 =
* New fields: heading with optional divider, time, multi-part name
* Internal label per form, added to the notification and the entry only

= 1.9.0 - 1.9.1 =
* Multiple recipients, CC and BCC, Reply-To on the sender address
* Confirmation as a message or a redirect, auto-responder

= 1.8.0 =
* Conditional display per field, evaluated on the client and verified on the server

== Upgrade Notice ==

= 1.25.0 =
Internal identifiers changed to meet the WordPress.org prefix rules. Existing forms are migrated automatically. If you use Webcraft Forms Premium, update it to 1.11.0 or later at the same time.

= 1.21.0 =
The plugin is now English by default and ships a complete German translation. German sites keep their familiar wording; other languages can be added with any PO/MO editor.

= 1.13.2 =
Script strings are translatable through the standard WordPress API. The builder works as before. New forms use ALTCHA by default; existing forms keep their current setting.
