Database Schema

  • JNext lesson
  • KPrevious lesson
  • FSearch lessons
  • EscClear search

Core Forms uses custom database tables for storing submissions, email logs, replies, polls, and poll votes. Forms themselves are stored as a WordPress custom post type.

Forms Storage

Forms are stored as the core-form custom post type in the standard WordPress wp_posts table.

  • post_title – The form title.
  • post_name – The form slug (used in shortcodes).
  • post_content – The form HTML markup.

Form settings are stored in the wp_postmeta table:

  • _cf_settings – Serialized array of form settings (save_submissions, redirect_url, required_fields, email_fields, custom_css, custom_js, actions, etc.).
  • cf_message_{code} – Individual form messages (e.g., cf_message_success, cf_message_error).

Submissions Table

Table name: {prefix}cf_submissions

Columns:

  • id (INT UNSIGNED, PRIMARY KEY, AUTO_INCREMENT) – Unique submission ID.
  • form_id (INT UNSIGNED, NOT NULL) – The form post ID this submission belongs to.
  • data (TEXT, NOT NULL) – JSON-encoded submission data. Each key is a field name, each value is the submitted value.
  • user_agent (TEXT, NULL) – The submitter’s browser user agent string.
  • ip_address (VARCHAR(255), NULL) – The submitter’s IP address.
  • referer_url (TEXT, NULL) – The page URL where the form was submitted.
  • is_spam (TINYINT(1), NOT NULL, DEFAULT 0) – Whether the submission was flagged as spam (1) or not (0).
  • submitted_at (TIMESTAMP, NOT NULL, DEFAULT CURRENT_TIMESTAMP) – When the submission was created.

Created: On plugin activation via _cf_create_submissions_table().

Migration: The is_spam column was added in version 3.1.2. Existing installations get it via the _cf_maybe_run_migrations() function.

Email Logs Table

Table name: {prefix}cf_email_logs

Columns:

  • id (INT UNSIGNED, PRIMARY KEY, AUTO_INCREMENT) – Unique log ID.
  • form_id (INT UNSIGNED, NOT NULL) – The form that triggered the email.
  • submission_id (INT UNSIGNED, NULL) – The submission associated with the email.
  • to_email (VARCHAR(255), NOT NULL) – The recipient email address.
  • from_email (VARCHAR(255), NULL) – The sender email address.
  • subject (VARCHAR(500), NULL) – The email subject line.
  • message (LONGTEXT, NULL) – The email body.
  • headers (TEXT, NULL) – Email headers as a newline-separated string.
  • status (VARCHAR(20), NOT NULL, DEFAULT ‘pending’) – Delivery status: pending, sent, or failed.
  • error_message (TEXT, NULL) – Error details if the email failed.
  • action_type (VARCHAR(50), DEFAULT ’email’) – The action type that sent the email (e.g., email, autoresponder).
  • sent_at (TIMESTAMP, NOT NULL, DEFAULT CURRENT_TIMESTAMP) – When the email was attempted.

Indexes:

  • form_idx on form_id
  • submission_idx on submission_id
  • status_idx on status

Created: On plugin activation via _cf_create_email_logs_table().

Submission Replies Table

Table name: {prefix}cf_submission_replies

Columns:

  • id (INT UNSIGNED, PRIMARY KEY, AUTO_INCREMENT) – Unique reply ID.
  • submission_id (INT UNSIGNED, NOT NULL) – The submission being replied to.
  • from_email (VARCHAR(255), NOT NULL) – The sender email.
  • to_email (VARCHAR(255), NOT NULL) – The recipient email.
  • subject (VARCHAR(500), NOT NULL) – The reply subject.
  • message (LONGTEXT, NOT NULL) – The reply body.
  • user_id (INT UNSIGNED, NOT NULL) – The WordPress user ID who sent the reply.
  • sent_at (TIMESTAMP, DEFAULT CURRENT_TIMESTAMP) – When the reply was sent.

Polls Table

Table name: {prefix}cf_polls

Columns:

  • id (INT UNSIGNED, PRIMARY KEY, AUTO_INCREMENT) – Unique poll ID.
  • post_id (INT UNSIGNED, NOT NULL) – The associated core-poll post ID.
  • question (TEXT, NOT NULL) – The poll question.
  • options (JSON) – Array of poll option strings.
  • settings (JSON) – Poll configuration (allow_multiple, show_results_before_vote, vote_limit).
  • status (VARCHAR(20), DEFAULT ‘active’) – Poll status: active or closed.
  • ends_at (DATETIME, NULL) – When the poll closes. NULL for no end date.
  • created_at (TIMESTAMP, DEFAULT CURRENT_TIMESTAMP) – When the poll was created.

Poll Votes Table

Table name: {prefix}cf_poll_votes

Columns:

  • id (INT UNSIGNED, PRIMARY KEY, AUTO_INCREMENT) – Unique vote ID.
  • poll_id (INT UNSIGNED, NOT NULL) – The poll being voted on.
  • option_index (INT, NOT NULL) – The index of the selected option in the poll’s options array.
  • ip_address (VARCHAR(255), NULL) – The voter’s IP address.
  • user_id (INT UNSIGNED, NULL) – The voter’s WordPress user ID (if logged in).
  • voted_at (TIMESTAMP, DEFAULT CURRENT_TIMESTAMP) – When the vote was cast.

Indexes:

  • poll_idx on poll_id
  • ip_idx on ip_address
  • user_idx on user_id

Plugin Options

Core Forms stores global settings and state in the WordPress wp_options table:

  • cf_settings – Global plugin settings (serialized array).
  • cf_db_version – Current database schema version (used for migrations).
  • core_forms_license – License key and activation status.
  • core_forms_license_last_check – Timestamp of last remote license verification.
  • core_forms_update_info – Cached update information (transient).

Multisite

On multisite installations, each site gets its own set of database tables. When a new site is added to the network, the wp_insert_site hook triggers table creation for the new site. The edit_forms capability is granted to the new site’s administrators.