=== FormLedger – Entries for Contact Form 7 ===
Contributors: chiraglad23
Tags: contact form 7, form entries, submissions, database, csv export
Requires at least: 6.4
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 1.0.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Store Contact Form 7 submissions in your WordPress database, then view, search, filter, export and manage them from the admin area.

== Description ==

FormLedger saves every successful Contact Form 7 submission to your site's own database, so a submission is never lost when an email fails to arrive. Entries are managed from a native WordPress admin screen under **Contact → CF7 Entries**.

The plugin works entirely inside your WordPress site. It does not send submission data to any external service, it contains no tracking or telemetry, and there are no limits on the number of forms or entries.

This is an independent plugin. It is not affiliated with or endorsed by the Contact Form 7 project.

= Features =

* Automatic storage of successful Contact Form 7 submissions, including when mail sending fails
* Unlimited forms and unlimited entries
* Supports text, email, tel, textarea, number, URL, date, select, checkbox, radio, acceptance, hidden, quiz and file fields
* Clean entries list (entry, form, submitted date, view and delete buttons) with pagination, sorting and screen options
* Search across entry ID, form title, field names and field values
* Filter by form (including deleted forms) and by date: today, yesterday, last 7 days, last 30 days, this month, last month or a custom range
* Read/unread status with bulk mark as read or unread
* Detailed entry screen showing every submitted field
* Individual and bulk delete
* CSV export of all, filtered or selected entries (with Form ID, Form Name, page URL and full file download links), UTF-8 encoded, with protection against spreadsheet formula injection
* Uploaded files are copied to a protected folder and can be downloaded securely by authorized users
* Privacy controls: IP address storage (off, anonymized or full), user agent storage, automatic data retention
* Integrates with the WordPress personal data exporter and eraser
* Multisite compatible: each site keeps its own entries
* Translation ready

= Privacy =

This plugin stores Contact Form 7 submission data in your site's database. Depending on your forms and settings, this may include names, email addresses, phone numbers, messages, uploaded files, IP addresses and browser user agents.

* IP address storage is **off** by default. You can choose to store an anonymized or full IP address.
* User agent storage is **off** by default.
* Automatic retention can delete entries older than 7, 30, 90, 180 or 365 days.
* The plugin registers a personal data exporter and eraser (Tools → Export Personal Data / Erase Personal Data). Entries are matched when they were submitted by the requesting user's account or contain a field whose value equals the requested email address.
* Suggested privacy policy text is added to Settings → Privacy.
* No data is sent to external services.

Using this plugin does not by itself make your website compliant with GDPR or any other law. You remain responsible for your own legal and privacy obligations, including your privacy policy and how long you keep data.

= Data Storage =

Entries are stored in three custom database tables that use your site's table prefix: `cf7em_entries`, `cf7em_entry_fields` and `cf7em_entry_attachments`.

Uploaded files are copied from Contact Form 7's temporary folder into `wp-content/uploads/cf7em-uploads/` with random, unguessable names. The folder contains an `.htaccess` file that blocks direct access on Apache. On Nginx, add a rule such as:

`location ^~ /wp-content/uploads/cf7em-uploads/ { deny all; }`

Files are only delivered through an authenticated admin download link.

Deactivating the plugin keeps all data. Deleting the plugin also keeps all data unless you enable **Delete all entries, uploaded files and settings when the plugin is deleted** under Contact → Entry Settings.

== Installation ==

1. Install and activate Contact Form 7.
2. Upload the `formledger` folder to `/wp-content/plugins/`, or install the plugin from Plugins → Add New.
3. Activate **FormLedger**.
4. Submit any Contact Form 7 form. The entry appears under **Contact → CF7 Entries**.
5. Review the privacy options under **Contact → Entry Settings**.

== Frequently Asked Questions ==

= Does it work without Contact Form 7? =

The plugin activates safely without Contact Form 7, and all previously stored entries remain viewable. New submissions can only be captured while Contact Form 7 is active. When Contact Form 7 is inactive, the entries screen moves to its own **CF7 Entries** menu.

= Are spam submissions stored? =

No. Entries are captured after Contact Form 7 has completed validation and its spam checks.

= Is anything stored if the email fails to send? =

Yes. Entries are saved just before Contact Form 7 sends mail, so a failed email does not mean a lost submission.

= What happens when I delete or rename a form? =

Entries are never deleted with their form. For existing forms, the current form title is shown. For deleted forms, the title stored at submission time is shown with a "(deleted form)" label. When a form was renamed, the entry screen also shows the title it was submitted under.

= Who can see entries? =

Administrators receive the `manage_cf7_entries` capability. You can grant it to other roles with a role editor plugin. Settings require the `manage_options` capability.

= How is CSV formula injection prevented? =

Cells that begin with `=`, `@`, a tab or a carriage return, or that begin with `+` or `-` and are not plain numbers, are prefixed with an apostrophe so spreadsheet applications treat them as text. Plain numbers such as `-123` are exported unchanged.

= Who can download uploaded files? =

Only logged-in users with the `manage_cf7_entries` capability. Download links (also included in CSV exports) send logged-out visitors to the login screen and refuse other users. Files are always sent as downloads, never displayed in the browser.

= Can I back up entries before removing the plugin? =

Yes. When "Delete all data when the plugin is deleted" is on, clicking Deactivate opens a dialog that offers to download all entries as a CSV file (opens in Excel) before you continue. WordPress only allows deleting a plugin after it is deactivated, so this is the last point where the plugin can offer a backup.

= Does it support multisite? =

Yes. Each site has its own entries, files and settings. Network activation sets up every site, and new sites are set up automatically.

= Is there a REST API? =

Not in this version. Submissions are never exposed publicly.

== Screenshots ==

1. Entries list with form, date and status filters.
2. Single entry screen with all submitted fields and attachments.
3. Privacy and retention settings.

== Changelog ==

= 1.0.0 =
* Initial release.

== Upgrade Notice ==

= 1.0.0 =
Initial release.
