=== Formatrica - Drag and Drop Form Builder === Contributors: thezoran Requires at least: 6.4 Tested up to: 6.9 Requires PHP: 8.1 Stable tag: 1.0.6 License: GPLv2 or later License URI: https://www.gnu.org/licenses/gpl-2.0.html Text Domain: formatrica Lightweight drag-and-drop WordPress form builder with reliable email delivery, strong security, and flexible integrations. By NexusPlugins. == Description == Formatrica was built to solve common frustrations with form builders: dated interfaces, overly complex workflows, and feature gating that makes proper evaluation difficult. It delivers a clean, modern drag-and-drop experience with practical defaults, so you can create a production-ready form in 5-6 clicks and add it to any page via shortcode or block. = Key Features = **Form Builder** * Intuitive drag-and-drop form builder (Vue.js + Pinia + SortableJS) * Real-time preview with live field editing * Form preview functionality with zoom control (50-100%) * 15 pre-built templates: Simple Contact, Business Contact, Newsletter Signup, Job Application, Appointment Request, Real Estate Inquiry, Course Registration, Event Registration, Customer Feedback, Support Ticket, Front-end Post Submission, Request a Quote, RSVP Response, Volunteer Signup, User Registration * Smart Quick Start notification for new forms **Field Types** * Text, Email, Telephone, Password * Textarea for long-form content * Select (single/multiple), Radio, Checkbox * File Upload with validation and size limits * Date Picker * Hidden fields for internal metadata * Custom Text blocks for static content * Submit Button with customizable labels **Security & Anti-Spam** * Honeypot protection (enabled by default) * CSRF token validation * IP-based rate limiting (configurable per form) * Multiple CAPTCHA providers: - Google reCAPTCHA v3 - Cloudflare Turnstile - FriendlyCaptcha * CAPTCHA secrets stored encrypted at rest with write-only admin controls * Minimum submission time detection * File upload validation with type and size restrictions **Privacy Controls** * IP address storage options: Full, Anonymized, or None * Default: Anonymized (removes last octet) * Auto-delete submissions after X days (optional) * GDPR-friendly data handling **Email Delivery** * Multiple delivery providers: - WordPress default (wp_mail) - SendGrid API - SMTP2GO API - Mailgun API (with EU/US region support) - Postmark API - Brevo API (formerly Sendinblue) - Amazon SES (with AWS Signature v4 authentication) - Custom SMTP - Mailpit (for development) * Encrypted credentials storage (AES-256-CBC) * Test email functionality * Customizable sender name, email, subject, and recipient * Smart defaults from WordPress settings * Verification emails for registration forms use the same provider configured in that form's settings **User Registration** * Special form type for WordPress user registration * Integrates with WordPress user creation flow * Email verification required: users must confirm their email before logging in * Verification emails respect each form's configured delivery provider (SMTP/API/wp_mail) * Login is blocked for unverified users with a clear message on wp-login.php **Integrations & Webhooks** * **Zapier**: Connect to 5,000+ apps via Webhooks by Zapier trigger * **Make.com**: Build visual automation workflows (formerly Integromat) * **Slack**: Instantly notify Slack channels via Incoming Webhooks * **WordPress Post**: Create pending posts (or other post types) with field mappings, taxonomy, and meta controls - Full ACF (Advanced Custom Fields) support with 20+ field types - Author mode: current user, fixed user, or anonymous - Featured image support, taxonomy term creation, custom post meta * **WooCommerce**: Generate orders and optional customer records directly from form submissions * **Mailchimp**: Subscribe contacts to audiences with field mapping and double opt-in * **Salesforce (Essentials)**: Create Web-to-Lead entries without OAuth * **HubSpot**: Submit contacts to HubSpot forms using a Private App token * **Custom Webhooks**: POST submission data to any endpoint * **Async integration queue**: Background processing for external webhooks (WordPress Cron) - Dramatically improves form submission performance (5-15s → <200ms) - 10 jobs per batch, 3 retry attempts with error logging - Keeps local integrations synchronous for data consistency * Secret key signing for verification (custom webhooks only) * Custom payload filtering via hooks * SSRF protection and security validation **Developer-Friendly** * Comprehensive [API documentation](https://docs.nexusplugins.com/products/formatrica) * 15+ action and filter hooks for extensibility * REST API endpoints for forms and submissions * Provider-specific payload filters (Slack, Mailchimp, Salesforce, HubSpot, WordPress Post) * PSR-4 autoloaded architecture with Service Layer design * Clean separation of concerns: Validation, Security, File Handling, Rendering, and Integrations layers * 22 single-responsibility classes for maintainability and testability * Database schema versioning system with migration support * Modular ES6 JavaScript with class-based structure * Vite-powered build system * Full TypeDoc-style inline documentation * Admin list improvements: Active/Inactive filters, Activate/Deactivate actions, and safe delete confirmations == Installation == 1. Upload the plugin files to `/wp-content/plugins/formatrica`, or install through the WordPress plugins screen 2. Activate the plugin through the "Plugins" screen 3. Visit **Formatrica → Forms** to create your first form 4. Use the shortcode `[formatrica id="123"]` or Gutenberg block to embed forms **First Time Setup** 1. Create your first form or apply a template 2. Configure email delivery in form settings 3. Test email delivery before going live == Frequently Asked Questions == = How do I send a test email? = Open a form in the builder, click **Settings**, navigate to **Email Settings** tab, configure your email settings, and click **Send test email**. = Where are submissions stored? = If storage is enabled, submissions are saved in `{$wpdb->prefix}formatrica_submissions` table with full field metadata. = Can I create WordPress users from forms? = Yes! Use the "User Registration" template or set form type to "User Registration" in settings. The form creates WordPress users and sends a verification email. The new user must confirm before logging in. The verification email is sent using the same delivery provider you configured for the form (SMTP/API/wp_mail). = Why is the new user blocked from logging in? = For security, login is blocked until the user confirms their email. The verification link redirects back to the WordPress login screen with a success message. = How do I send Slack notifications? = Open a form, head to **Settings → Integrations**, enable Slack, and paste the webhook URL. Message templates support placeholders such as `{{form_title}}` and `{{field:email}}`. See the [Slack integration guide](https://docs.nexusplugins.com/products/formatrica) for a detailed walkthrough. = How do I add contacts to Mailchimp? = Enable **Mailchimp** in the Integrations tab, add your API key, fetch or paste the audience ID, then map the form fields for email and names. Toggle double opt-in if you want Mailchimp to send confirmation emails. See the [Mailchimp integration guide](https://docs.nexusplugins.com/products/formatrica) for screenshots and payload examples. = Can I push submissions into Salesforce or HubSpot? = Yes. Enable **Salesforce (Essentials)** or **HubSpot**, provide the required identifiers (organisation ID, portal ID, form GUID, etc.) and map the fields you want to sync. Salesforce uses Web-to-Lead, while HubSpot submits to the Forms API with optional GDPR consent. Refer to the [Salesforce](https://docs.nexusplugins.com/products/formatrica) and [HubSpot](https://docs.nexusplugins.com/products/formatrica) integration guides. = Do verification emails use my SMTP/API settings? = Yes. If you configured a delivery provider in the form's Email Settings, verification emails are routed through the same provider. If no provider is set (e.g., registration created outside a form context), the plugin falls back to wp_mail(). = How do I customize form styling? = Add custom CSS in **Settings → Advanced → Custom CSS** per form, or target `.formatrica` classes in your theme. = What file types are allowed for uploads? = Default: JPG, PNG, GIF, WebP, PDF, DOC, DOCX, TXT. Customize via `formatrica_allowed_file_types` filter. = How do I anonymize IP addresses? = Go to **Settings → Privacy** and select "Store anonymized IP address". This removes the last octet (e.g., 192.168.1.xxx). = Can submissions be automatically deleted? = Yes! In **Settings → Privacy**, enable "Automatically delete old submissions" and set retention period (default: 90 days). = How do I duplicate a form? = Hover over any form in the list and click **Duplicate**. The copy will have " (Copy)" appended to the title. = How do I disable a form without deleting its data? = Use the **Deactivate** action in the Forms list. Deactivated forms are hidden on the frontend and won’t accept submissions, but you keep all data. You can re-enable via **Activate**. = What’s the difference between Deactivate and Delete permanently? = Deactivate is a safe, reversible action and keeps submissions. **Delete permanently** removes the form and all its submissions after a confirmation. This cannot be undone. = Can I filter between Active and Inactive forms? = Yes. Use the filters above the forms table: **All**, **Active**, **Inactive**. Counts are shown for each. = How do I connect my forms to Zapier? = Open your form, go to **Settings → Integrations**, enable Zapier, and paste your Zapier webhook URL. In Zapier, create a Zap using "Webhooks by Zapier" → "Catch Hook". Submit a test form to send data to Zapier, then build your workflow. = How do I connect my forms to Make.com? = Open your form, go to **Settings → Integrations**, enable Make, and paste your Make webhook URL. In Make.com, create a Scenario using "Webhooks" → "Custom webhook". Submit a test form to determine the data structure, then build your scenario. = What data is sent to integrations? = Integrations receive JSON with form title, submission data, field metadata, and context (IP, user agent). Use the `formatrica_webhook_payload` filter to customize the payload per integration. = Does it work with page builders? = Yes! Use the `[formatrica id="123"]` shortcode in any page builder that supports WordPress shortcodes. = Is it compatible with multilingual plugins? = The plugin is translation-ready with full i18n support. Text domain: `formatrica` = Is source code for built assets included? = Yes. The plugin package includes the human-readable frontend/admin source under `src/` and the compiled runtime assets under `build/`. Build command: `npm ci && npm run build`. == Screenshots == 1. Drag-and-drop form builder with live preview 2. Form settings with tabs: General, Email Settings, Integrations, Security, Privacy, Advanced 3. Form templates library 4. Field editor with validation options 5. Frontend form with inline validation == Hooks & Filters == = Action Hooks = **formatrica_before_submission** Fires before processing a form submission. `do_action('formatrica_before_submission', $form_id, $form, $request_data, $context);` **formatrica_after_submission** Fires after successful submission processing. `do_action('formatrica_after_submission', $form_id, $sanitised, $result, $form, $context);` **formatrica_user_registered** Fires after a new WordPress user is registered via form. `do_action('formatrica_user_registered', $user_id, $data);` **formatrica_webhook_failed** Fires when webhook delivery fails. `do_action('formatrica_webhook_failed', $error_data);` **formatrica_integration_dispatch** Fires when an integration ID is not handled by the built-in dispatchers, allowing custom providers. `do_action('formatrica_integration_dispatch', $integration_id, $settings, $form, $payload, $context, $field_meta);` = Filter Hooks = **formatrica_submission_request** Filter raw submission data before validation. `apply_filters('formatrica_submission_request', $request_data, $form_id, $form, $context);` **formatrica_sanitized_submission** Filter sanitized submission data before processing. `apply_filters('formatrica_sanitized_submission', $sanitised, $form_id, $form, $request_data, $context);` **formatrica_webhook_payload** Filter webhook payload before sending to integrations (Zapier, Make, Slack) or custom webhooks. The `$context` parameter includes an `integration` key identifying the target. `apply_filters('formatrica_webhook_payload', $body, $form, $payload, $context, $field_meta);` **formatrica_slack_payload** Filter the Slack payload before dispatching to the incoming webhook. `apply_filters('formatrica_slack_payload', $body, $form, $payload, $context, $field_meta);` **formatrica_mailchimp_payload** Filter the Mailchimp member payload before it is sent via the API. `apply_filters('formatrica_mailchimp_payload', $body, $form, $payload, $context, $field_meta);` **formatrica_salesforce_payload** Filter the Salesforce Web-to-Lead form data before submission. `apply_filters('formatrica_salesforce_payload', $data, $form, $payload, $context, $field_meta);` **formatrica_hubspot_payload** Filter the HubSpot Forms API payload before dispatch. `apply_filters('formatrica_hubspot_payload', $body, $form, $payload, $context, $field_meta);` **formatrica_duplicate_title** Filter duplicated form title. `apply_filters('formatrica_duplicate_title', $title, $original_form);` **formatrica_min_submission_time** Filter minimum time between page load and submission (anti-bot). `apply_filters('formatrica_min_submission_time', 2, $form_id);` **formatrica_max_upload_size** Filter maximum file upload size in MB. `apply_filters('formatrica_max_upload_size', $max_size, $field);` **formatrica_allowed_file_types** Filter allowed MIME types for file uploads. `apply_filters('formatrica_allowed_file_types', $allowed_types, $field);` **formatrica_max_image_dimension** Filter maximum image dimension in pixels. `apply_filters('formatrica_max_image_dimension', 4096, $field);` **formatrica_recaptcha_v3_min_score** Filter minimum reCAPTCHA v3 score threshold. `apply_filters('formatrica_recaptcha_v3_min_score', 0.5, $form_id);` For detailed examples, see the [plugin documentation](https://docs.nexusplugins.com/products/formatrica). == REST API == Formatrica registers REST API endpoints under the `formatrica/v1` namespace. All admin endpoints require the `manage_options` capability and a valid REST nonce. = Public Endpoints = The following endpoints are intentionally public (no authentication required) because they serve front-end form functionality for unauthenticated visitors: **POST /formatrica/v1/forms/{form_id}/submissions** Accepts a form submission from any visitor. Security is enforced at the application layer: CSRF token validation, honeypot field detection, minimum submission time check, IP-based rate limiting, CAPTCHA verification, and full field sanitisation/validation. **GET /formatrica/v1/utility/countries** Returns a read-only list of country names for front-end country select fields. No user data is accepted or stored. **GET /formatrica/v1/utility/states/{country}** Returns a read-only list of states/provinces for a given ISO 3166-1 alpha-2 country code (e.g. `US`, `DE`). The country code is validated to exactly two uppercase letters. No user data is accepted or stored. = Admin Endpoints (require `manage_options` + REST nonce) = * `GET/POST /formatrica/v1/forms` — List or create forms * `GET/PUT/PATCH/DELETE /formatrica/v1/forms/{form_id}` — Read, update, or delete a form * `POST /formatrica/v1/emails/test` — Send a test email * `GET /formatrica/v1/wp/post-types` — List available post types * `GET /formatrica/v1/woocommerce/catalog` — List WooCommerce products/categories * `POST /formatrica/v1/integrations/mailchimp/lists` — Fetch Mailchimp audience lists * `GET/POST /formatrica/v1/settings/email` — Read or update email settings * `POST /formatrica/v1/settings/email/test` — Test email configuration * `GET /formatrica/v1/settings/email/diagnostics` — Email delivery diagnostics == External services == Formatrica does not contact any external service by default. Each service below is used only when a site administrator explicitly enables and configures it for a form. = CAPTCHA Verification = When a CAPTCHA provider is enabled on a form, the visitor's browser loads the provider's JavaScript widget and, on submission, the visitor's IP address and a verification token are sent to that provider's server-side verification endpoint. This happens once per form submission. * **Google reCAPTCHA v3** — Verifies submissions are from real users by scoring browser behaviour. Data sent: visitor IP address, verification token, site key. [Terms of Service](https://policies.google.com/terms) | [Privacy Policy](https://policies.google.com/privacy) * **Cloudflare Turnstile** — Non-intrusive bot detection challenge. Data sent: visitor IP address, verification token, site key. [Terms of Service](https://www.cloudflare.com/terms/) | [Privacy Policy](https://www.cloudflare.com/privacypolicy/) * **FriendlyCaptcha** — Privacy-focused proof-of-work CAPTCHA. Data sent: visitor IP address, puzzle solution, site key. [Terms of Service](https://friendlycaptcha.com/legal/terms/) | [Privacy Policy](https://friendlycaptcha.com/legal/privacy-end-users/) = Email Delivery = When a third-party email delivery provider is configured, submission notification emails are transmitted to the provider's API each time a form is submitted. Data sent includes: recipient address, sender name and email, subject line, and the message body containing the submitted form data. * **SendGrid** (Twilio) — Transactional email API. [Terms of Service](https://www.twilio.com/en-us/legal/tos) | [Privacy Policy](https://www.twilio.com/en-us/legal/privacy) * **SMTP2GO** — Transactional email API. [Terms of Service](https://www.smtp2go.com/terms/) | [Privacy Policy](https://www.smtp2go.com/privacy/) * **Mailgun** (Sinch) — Transactional email API. [Terms of Service](https://www.mailgun.com/legal/terms/) | [Privacy Policy](https://www.mailgun.com/legal/privacy-policy/) * **Postmark** (ActiveCampaign) — Transactional email API. [Terms of Service](https://postmarkapp.com/terms-of-service) | [Privacy Policy](https://postmarkapp.com/privacy-policy) * **Brevo** (formerly Sendinblue) — Transactional email API. [Terms of Service](https://www.brevo.com/legal/termsofuse/) | [Privacy Policy](https://www.brevo.com/legal/privacypolicy/) * **Amazon SES** (AWS) — Transactional email API. Uses AWS Signature v4 authentication. [Terms of Service](https://aws.amazon.com/service-terms/) | [Privacy Policy](https://aws.amazon.com/privacy/) Custom SMTP and Mailpit send data to your own mail server. The default WordPress provider uses `wp_mail()` with no external API call. = Integrations = When an integration is enabled and configured by the site administrator, form submission data is sent to the configured endpoint upon each form submission. Data sent includes: form title, submitted field values, and field metadata. The Zapier, Make.com, and custom webhook integrations also include the submitter's IP address and user agent in the payload. * **Zapier** — Automation platform. Receives a JSON webhook with full submission data on each form submission. [Terms of Service](https://zapier.com/legal/terms-of-service) | [Privacy Policy](https://zapier.com/privacy) * **Make.com** (formerly Integromat) — Automation platform. Receives a JSON webhook with full submission data on each form submission. [Terms of Service](https://www.make.com/en/terms) | [Privacy Policy](https://www.make.com/en/privacy-notice) * **Slack** — Team messaging. Sends a formatted message containing form title and submitted field values to a Slack Incoming Webhook URL. No IP address or user agent is sent. [Terms of Service](https://slack.com/terms-of-service) | [Privacy Policy](https://slack.com/trust/privacy/privacy-policy) * **Mailchimp** (Intuit) — Email marketing. Subscribes the visitor's email address and optionally mapped name fields to a Mailchimp audience list. [Terms of Service](https://mailchimp.com/legal/terms/) | [Privacy Policy](https://www.intuit.com/privacy/statement/) * **Salesforce** — CRM. Submits mapped lead fields via the Web-to-Lead endpoint. Only the fields explicitly mapped by the administrator are sent. [Terms of Service](https://www.salesforce.com/company/legal/) | [Privacy Policy](https://www.salesforce.com/company/privacy/) * **HubSpot** — CRM. Submits mapped contact properties to the HubSpot Forms API using a Private App token. Only the fields explicitly mapped by the administrator are sent. [Terms of Service](https://legal.hubspot.com/terms-of-service) | [Privacy Policy](https://legal.hubspot.com/privacy-policy) * **Custom Webhooks** — Sends a signed JSON payload to an arbitrary endpoint URL configured by the site administrator. == Privacy == = Local Data Storage = * Submissions are stored in a custom database table on your WordPress site when storage is enabled. * IP address storage can be set to Full, Anonymized (last octet removed), or None per form. * Automatic submission deletion can be enabled with a configurable retention period. * API keys and secrets are encrypted at rest using AES-256-CBC and are never exposed in the admin UI or REST API responses. == Changelog == = 1.0.6 - 2026-03-06 = * Escaped all remaining output variables at the echo boundary (escape-late pattern) per WP.org reviewer feedback * Hardened all wp_add_inline_style() and wp_add_inline_script() calls with wp_kses_no_null and close-tag neutralisation * Removed phpcs:ignore EscapeOutput annotations replaced by proper escaping = 1.0.5 - 2026-02-24 = * Removed all `use function` imports for WordPress global functions across 31 PHP files to resolve PHP "name already in use" errors in certain hosting environments = 1.0.4 - 2026-02-24 = * Converted all inline `