# Inletform 1.0.0

Build a clear inquiry form, keep the context, and review it in WordPress. Inletform is an original native WordPress plugin. It stores validated inquiries in your own site's private inbox. **It does not send email.** A storage confirmation means a database record was written, not that somebody read it or an email was delivered.

## Install the right ZIP

Prerequisites: a backed-up WordPress site (support target 6.6+) with PHP 8.1+ and its mbstring extension, a working WordPress database, and administrator access. The observed QA environment is WordPress 7.1.3 / PHP 8.5.5 with the official SQLite integration. The full MySQL/MariaDB, theme and host compatibility matrix is unverified; try a staging copy first.

1. Download and unzip the complete **inletform-1.0.0.zip** documentation package. Keep **dist/inletform-plugin-1.0.0.zip**, included in the extracted package’s **dist/** folder, zipped. In WordPress, open Plugins → Add Plugin → Upload Plugin and choose that included **dist/inletform-plugin-1.0.0.zip**, not the full documentation ZIP or the unzipped plugin folder.
2. Install, then Activate. Open **Inletform** in the WordPress administrator menu.
3. Choose **Create form**. Edit the title, explanation, button and privacy notice. Field cards let you edit labels, help, type, choices and required state. Add/remove fields or move them with the buttons. No code or JSON is needed.
4. Choose **Published**, then **Save form**. Drafts preserve their entries and stop accepting inquiries.
5. Copy the displayed `[inletform id="ID"]` shortcode to a WordPress page (a Shortcode block or classic editor). Use the actual generated ID.
6. Open the page as a visitor. Send invented details ending in `.invalid`, then inspect **Inletform → Entries**. Open the reference, check every answer and choose **Mark reviewed**. This is the complete setup check, not just a successful activation.

A filled configuration lives in `samples/studio-inquiry.json`. In a form editor, use **Import form JSON**, inspect the loaded field cards, then Save. Import does not save automatically and does not replace or delete old entries. Export form JSON downloads a reusable configuration containing no submissions. Reopening and re-exporting an unchanged configuration preserves its fields, labels, settings and choices.

## Field behavior

Up to 20 fields: single line (200 characters), email (254), long answer (2,000), dropdown/radio (2–12 unique choices), consent checkbox and valid ISO calendar date. Labels and help are plain Unicode text, without markup. Required fields validate both in the browser and on the server. Errors preserve safe typed answers for correction. A schema change or expired WordPress nonce requires reloading; copy your answers before doing so. Native full-page POST works without front-end JavaScript. Two shortcode instances use different control IDs.

Stable field keys are generated by the editor; keep keys stable when using JSON. Existing entries contain the exact labels/types/answers from submission time. Removing/renaming a field does not rewrite old inquiries. There is no public submission read API, payment, attachment upload, external service, webhook, conditional logic, multi-step flow or account creation.

## Inbox and export

Only WordPress administrators (`manage_options`) can edit forms, view Entries or export them. The inbox shows 20 entries per page with UTC timestamps and a stored reference. Marking reviewed persists the review state. **Export entries CSV** exports up to 5,000 stored entries for that form, newest first, including historical field labels and missing-value blanks. The form stops accepting new inquiries at 5,000 entries, with an explicit unsaved error. There is no silent truncation, auto-delete or purge. Plan retention before public use.

CSV is UTF-8 with BOM, standard quote/newline handling and fixed metadata columns. Potential spreadsheet formula cells beginning with `=`, `+`, `-` or `@` (including after whitespace) receive an initial apostrophe; this deliberate safety prefix is not part of the original stored answer. Checkbox consent is `yes`. Repeated submissions of the same unchanged request return the same reference; changed data with an already-used request is rejected. A new page load creates a new request.

## Data, privacy and spam limits

Inletform stores form schemas in WordPress post meta and inquiries in `PREFIX_inletform_entries`, including a request hash, form ID, UTC timestamp, review state and answer snapshot. It adds no IP, user agent, tracking ID, analytics, outbound network calls or email. Browser/host logs are outside this plugin's control. **Answers are not encrypted at rest by the plugin.** Site admins, database access and backups can expose them. Supply an accurate privacy/retention notice, HTTPS, protected administrator access and appropriate backups. Do not use the example privacy text as a claim about your own operating practices. Do not collect medical, payment or other sensitive data with this example.

WordPress nonce, honeypot, payload size cap and unique request key provide basic friction and duplicate protection; they do not replace rate limiting, server abuse controls or a comprehensive anti-spam service. Cached pages may serve expired nonces. Where public abuse is a concern, establish appropriate hosting protections before publishing. A database failure returns an unsaved error, never success. Test with invented details after upgrades or form changes.

No permanent deletion or uninstall cleanup is provided. Deactivation preserves forms and entries. For retention work, use your authorized database/export process and a current backup; never remove data based solely on this guide.

## Free visitor rehearsal

Open `preview/index.html` locally. It runs offline and demonstrates the visitor experience with fictional data, browser validation, review and editing. It sends no requests, stores nothing and is not the native plugin or a substitute for inbox QA. It uses the separate included `preview/LICENSE.txt` approved free terms. `hosted/metrics.js` is **not** part of either offline ZIP; it is a publisher-only fixed anonymous demo-action adapter that honors DNT/GPC and defaults internal. Hosted markup must mark its real same-origin plugin ZIP link with `data-inletform-download="plugin"`. Only a click on that exact ZIP path emits the fixed `plugin_download_requested` event. A request event is not proof of a successful download. The publisher must verify the actual download and live event persistence separately.

## Development and testing

The plugin is editable PHP/CSS/JS with no build step or runtime dependencies bundled beyond WordPress APIs. Install its `inletform/` directory as a plugin. Development scripts/tests and the isolated WordPress runtime are retained outside customer ZIPs. The delivered plugin was checked with pure rule assertions, native WordPress storage/capability/export assertions, and DOM checks; real browser results remain separate in producer QA. WordPress/SQLite are test-only dependencies, not redistributed in this product. See THIRD_PARTY.md.

## License and offer

The complete native plugin in `inletform/`, including PHP, JavaScript and CSS, is licensed under GNU GPL version 2 or later. Its complete corresponding source and license text are included in `inletform/LICENSE.txt`. Recipients may use, modify and redistribute the plugin, including for a fee, subject to the GPL. The outer LICENSE.txt applies the existing customer terms only to the remaining original documentation/sample materials; those terms do not restrict GPL-covered plugin or source rights. The separate free rehearsal retains its existing license. The native plugin is the USD29 one-time offer selected for this candidate; checkout/provider activation is a separate publisher step. Documentation is included. No hosted service, guaranteed personal support, SLA, update schedule, email delivery or business-result guarantee is included. Third-party rights remain separate.
